fib_notifier.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/rtnetlink.h>
  3. #include <linux/notifier.h>
  4. #include <linux/socket.h>
  5. #include <linux/kernel.h>
  6. #include <linux/export.h>
  7. #include <net/net_namespace.h>
  8. #include <net/fib_notifier.h>
  9. #include <net/ip_fib.h>
  10. int call_fib4_notifier(struct notifier_block *nb,
  11. enum fib_event_type event_type,
  12. struct fib_notifier_info *info)
  13. {
  14. info->family = AF_INET;
  15. return call_fib_notifier(nb, event_type, info);
  16. }
  17. int call_fib4_notifiers(struct net *net, enum fib_event_type event_type,
  18. struct fib_notifier_info *info)
  19. {
  20. ASSERT_RTNL();
  21. info->family = AF_INET;
  22. net->ipv4.fib_seq++;
  23. return call_fib_notifiers(net, event_type, info);
  24. }
  25. static unsigned int fib4_seq_read(struct net *net)
  26. {
  27. ASSERT_RTNL();
  28. return net->ipv4.fib_seq + fib4_rules_seq_read(net);
  29. }
  30. static int fib4_dump(struct net *net, struct notifier_block *nb,
  31. struct netlink_ext_ack *extack)
  32. {
  33. int err;
  34. err = fib4_rules_dump(net, nb, extack);
  35. if (err)
  36. return err;
  37. return fib_notify(net, nb, extack);
  38. }
  39. static const struct fib_notifier_ops fib4_notifier_ops_template = {
  40. .family = AF_INET,
  41. .fib_seq_read = fib4_seq_read,
  42. .fib_dump = fib4_dump,
  43. .owner = THIS_MODULE,
  44. };
  45. int __net_init fib4_notifier_init(struct net *net)
  46. {
  47. struct fib_notifier_ops *ops;
  48. net->ipv4.fib_seq = 0;
  49. ops = fib_notifier_ops_register(&fib4_notifier_ops_template, net);
  50. if (IS_ERR(ops))
  51. return PTR_ERR(ops);
  52. net->ipv4.notifier_ops = ops;
  53. return 0;
  54. }
  55. void __net_exit fib4_notifier_exit(struct net *net)
  56. {
  57. fib_notifier_ops_unregister(net->ipv4.notifier_ops);
  58. }