summaryrefslogtreecommitdiffstats
path: root/net/ipv4/devinet.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/devinet.c')
-rw-r--r--net/ipv4/devinet.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index df14815a3b8c..a7dd088d5fc9 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -176,6 +176,7 @@ EXPORT_SYMBOL(__ip_dev_find);
176static void rtmsg_ifa(int event, struct in_ifaddr *, struct nlmsghdr *, u32); 176static void rtmsg_ifa(int event, struct in_ifaddr *, struct nlmsghdr *, u32);
177 177
178static BLOCKING_NOTIFIER_HEAD(inetaddr_chain); 178static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);
179static BLOCKING_NOTIFIER_HEAD(inetaddr_validator_chain);
179static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, 180static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
180 int destroy); 181 int destroy);
181#ifdef CONFIG_SYSCTL 182#ifdef CONFIG_SYSCTL
@@ -441,6 +442,8 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
441{ 442{
442 struct in_device *in_dev = ifa->ifa_dev; 443 struct in_device *in_dev = ifa->ifa_dev;
443 struct in_ifaddr *ifa1, **ifap, **last_primary; 444 struct in_ifaddr *ifa1, **ifap, **last_primary;
445 struct in_validator_info ivi;
446 int ret;
444 447
445 ASSERT_RTNL(); 448 ASSERT_RTNL();
446 449
@@ -471,6 +474,23 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
471 } 474 }
472 } 475 }
473 476
477 /* Allow any devices that wish to register ifaddr validtors to weigh
478 * in now, before changes are committed. The rntl lock is serializing
479 * access here, so the state should not change between a validator call
480 * and a final notify on commit. This isn't invoked on promotion under
481 * the assumption that validators are checking the address itself, and
482 * not the flags.
483 */
484 ivi.ivi_addr = ifa->ifa_address;
485 ivi.ivi_dev = ifa->ifa_dev;
486 ret = blocking_notifier_call_chain(&inetaddr_validator_chain,
487 NETDEV_UP, &ivi);
488 ret = notifier_to_errno(ret);
489 if (ret) {
490 inet_free_ifa(ifa);
491 return ret;
492 }
493
474 if (!(ifa->ifa_flags & IFA_F_SECONDARY)) { 494 if (!(ifa->ifa_flags & IFA_F_SECONDARY)) {
475 prandom_seed((__force u32) ifa->ifa_local); 495 prandom_seed((__force u32) ifa->ifa_local);
476 ifap = last_primary; 496 ifap = last_primary;
@@ -1356,6 +1376,19 @@ int unregister_inetaddr_notifier(struct notifier_block *nb)
1356} 1376}
1357EXPORT_SYMBOL(unregister_inetaddr_notifier); 1377EXPORT_SYMBOL(unregister_inetaddr_notifier);
1358 1378
1379int register_inetaddr_validator_notifier(struct notifier_block *nb)
1380{
1381 return blocking_notifier_chain_register(&inetaddr_validator_chain, nb);
1382}
1383EXPORT_SYMBOL(register_inetaddr_validator_notifier);
1384
1385int unregister_inetaddr_validator_notifier(struct notifier_block *nb)
1386{
1387 return blocking_notifier_chain_unregister(&inetaddr_validator_chain,
1388 nb);
1389}
1390EXPORT_SYMBOL(unregister_inetaddr_validator_notifier);
1391
1359/* Rename ifa_labels for a device name change. Make some effort to preserve 1392/* Rename ifa_labels for a device name change. Make some effort to preserve
1360 * existing alias numbering and to create unique labels if possible. 1393 * existing alias numbering and to create unique labels if possible.
1361*/ 1394*/