fib_notifier.c 1.5 KB

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