in.c (219828) | in.c (222143) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (C) 2001 WIDE Project. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 17 unchanged lines hidden (view full) --- 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * @(#)in.c 8.4 (Berkeley) 1/9/95 31 */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1982, 1986, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (C) 2001 WIDE Project. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 17 unchanged lines hidden (view full) --- 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * @(#)in.c 8.4 (Berkeley) 1/9/95 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet/in.c 219828 2011-03-21 14:19:40Z pluknet $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/in.c 222143 2011-05-20 19:12:20Z qingli $"); |
35 36#include "opt_mpath.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/sockio.h> 41#include <sys/malloc.h> 42#include <sys/priv.h> --- 22 unchanged lines hidden (view full) --- 65#include <netinet/udp_var.h> 66 67static int in_mask2len(struct in_addr *); 68static void in_len2mask(struct in_addr *, int); 69static int in_lifaddr_ioctl(struct socket *, u_long, caddr_t, 70 struct ifnet *, struct thread *); 71 72static int in_addprefix(struct in_ifaddr *, int); | 35 36#include "opt_mpath.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/sockio.h> 41#include <sys/malloc.h> 42#include <sys/priv.h> --- 22 unchanged lines hidden (view full) --- 65#include <netinet/udp_var.h> 66 67static int in_mask2len(struct in_addr *); 68static void in_len2mask(struct in_addr *, int); 69static int in_lifaddr_ioctl(struct socket *, u_long, caddr_t, 70 struct ifnet *, struct thread *); 71 72static int in_addprefix(struct in_ifaddr *, int); |
73static int in_scrubprefix(struct in_ifaddr *); | 73static int in_scrubprefix(struct in_ifaddr *, u_int); |
74static void in_socktrim(struct sockaddr_in *); 75static int in_ifinit(struct ifnet *, 76 struct in_ifaddr *, struct sockaddr_in *, int); 77static void in_purgemaddrs(struct ifnet *); 78 79static VNET_DEFINE(int, subnetsarelocal); 80#define V_subnetsarelocal VNET(subnetsarelocal) 81SYSCTL_VNET_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW, --- 461 unchanged lines hidden (view full) --- 543 * QL: XXX 544 * Need to scrub the prefix here in case 545 * the issued command is SIOCAIFADDR with 546 * the same address, but with a different 547 * prefix length. And if the prefix length 548 * is the same as before, then the call is 549 * un-necessarily executed here. 550 */ | 74static void in_socktrim(struct sockaddr_in *); 75static int in_ifinit(struct ifnet *, 76 struct in_ifaddr *, struct sockaddr_in *, int); 77static void in_purgemaddrs(struct ifnet *); 78 79static VNET_DEFINE(int, subnetsarelocal); 80#define V_subnetsarelocal VNET(subnetsarelocal) 81SYSCTL_VNET_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW, --- 461 unchanged lines hidden (view full) --- 543 * QL: XXX 544 * Need to scrub the prefix here in case 545 * the issued command is SIOCAIFADDR with 546 * the same address, but with a different 547 * prefix length. And if the prefix length 548 * is the same as before, then the call is 549 * un-necessarily executed here. 550 */ |
551 in_ifscrub(ifp, ia); | 551 in_ifscrub(ifp, ia, 0); |
552 ia->ia_sockmask = ifra->ifra_mask; 553 ia->ia_sockmask.sin_family = AF_INET; 554 ia->ia_subnetmask = 555 ntohl(ia->ia_sockmask.sin_addr.s_addr); 556 maskIsNew = 1; 557 } 558 if ((ifp->if_flags & IFF_POINTOPOINT) && 559 (ifra->ifra_dstaddr.sin_family == AF_INET)) { | 552 ia->ia_sockmask = ifra->ifra_mask; 553 ia->ia_sockmask.sin_family = AF_INET; 554 ia->ia_subnetmask = 555 ntohl(ia->ia_sockmask.sin_addr.s_addr); 556 maskIsNew = 1; 557 } 558 if ((ifp->if_flags & IFF_POINTOPOINT) && 559 (ifra->ifra_dstaddr.sin_family == AF_INET)) { |
560 in_ifscrub(ifp, ia); | 560 in_ifscrub(ifp, ia, 0); |
561 ia->ia_dstaddr = ifra->ifra_dstaddr; 562 maskIsNew = 1; /* We lie; but the effect's the same */ 563 } 564 if (ifra->ifra_addr.sin_family == AF_INET && 565 (hostIsNew || maskIsNew)) 566 error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0); 567 if (error != 0 && iaIsNew) 568 break; --- 11 unchanged lines hidden (view full) --- 580 EVENTHANDLER_INVOKE(ifaddr_event, ifp); 581 } 582 goto out; 583 584 case SIOCDIFADDR: 585 /* 586 * in_ifscrub kills the interface route. 587 */ | 561 ia->ia_dstaddr = ifra->ifra_dstaddr; 562 maskIsNew = 1; /* We lie; but the effect's the same */ 563 } 564 if (ifra->ifra_addr.sin_family == AF_INET && 565 (hostIsNew || maskIsNew)) 566 error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0); 567 if (error != 0 && iaIsNew) 568 break; --- 11 unchanged lines hidden (view full) --- 580 EVENTHANDLER_INVOKE(ifaddr_event, ifp); 581 } 582 goto out; 583 584 case SIOCDIFADDR: 585 /* 586 * in_ifscrub kills the interface route. 587 */ |
588 in_ifscrub(ifp, ia); | 588 in_ifscrub(ifp, ia, LLE_STATIC); |
589 590 /* 591 * in_ifadown gets rid of all the rest of 592 * the routes. This is not quite the right 593 * thing to do, but at least if we are running 594 * a routing process they will come back. 595 */ 596 in_ifadown(&ia->ia_ifa, 1); --- 227 unchanged lines hidden (view full) --- 824 825 return (EOPNOTSUPP); /*just for safety*/ 826} 827 828/* 829 * Delete any existing route for an interface. 830 */ 831void | 589 590 /* 591 * in_ifadown gets rid of all the rest of 592 * the routes. This is not quite the right 593 * thing to do, but at least if we are running 594 * a routing process they will come back. 595 */ 596 in_ifadown(&ia->ia_ifa, 1); --- 227 unchanged lines hidden (view full) --- 824 825 return (EOPNOTSUPP); /*just for safety*/ 826} 827 828/* 829 * Delete any existing route for an interface. 830 */ 831void |
832in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia) | 832in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia, u_int flags) |
833{ 834 | 833{ 834 |
835 in_scrubprefix(ia); | 835 in_scrubprefix(ia, flags); |
836} 837 838/* 839 * Initialize an interface's internet address 840 * and routing table entry. 841 */ 842static int 843in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, --- 38 unchanged lines hidden (view full) --- 882 LIST_REMOVE(ia, ia_hash); 883 IN_IFADDR_WUNLOCK(); 884 return (error); 885 } 886 } 887 splx(s); 888 if (scrub) { 889 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; | 836} 837 838/* 839 * Initialize an interface's internet address 840 * and routing table entry. 841 */ 842static int 843in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, --- 38 unchanged lines hidden (view full) --- 882 LIST_REMOVE(ia, ia_hash); 883 IN_IFADDR_WUNLOCK(); 884 return (error); 885 } 886 } 887 splx(s); 888 if (scrub) { 889 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; |
890 in_ifscrub(ifp, ia); | 890 in_ifscrub(ifp, ia, LLE_STATIC); |
891 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 892 } 893 if (IN_CLASSA(i)) 894 ia->ia_netmask = IN_CLASSA_NET; 895 else if (IN_CLASSB(i)) 896 ia->ia_netmask = IN_CLASSB_NET; 897 else 898 ia->ia_netmask = IN_CLASSC_NET; --- 191 unchanged lines hidden (view full) --- 1090extern void arp_ifscrub(struct ifnet *ifp, uint32_t addr); 1091 1092/* 1093 * If there is no other address in the system that can serve a route to the 1094 * same prefix, remove the route. Hand over the route to the new address 1095 * otherwise. 1096 */ 1097static int | 891 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 892 } 893 if (IN_CLASSA(i)) 894 ia->ia_netmask = IN_CLASSA_NET; 895 else if (IN_CLASSB(i)) 896 ia->ia_netmask = IN_CLASSB_NET; 897 else 898 ia->ia_netmask = IN_CLASSC_NET; --- 191 unchanged lines hidden (view full) --- 1090extern void arp_ifscrub(struct ifnet *ifp, uint32_t addr); 1091 1092/* 1093 * If there is no other address in the system that can serve a route to the 1094 * same prefix, remove the route. Hand over the route to the new address 1095 * otherwise. 1096 */ 1097static int |
1098in_scrubprefix(struct in_ifaddr *target) | 1098in_scrubprefix(struct in_ifaddr *target, u_int flags) |
1099{ 1100 struct in_ifaddr *ia; 1101 struct in_addr prefix, mask, p; 1102 int error = 0; 1103 struct sockaddr_in prefix0, mask0; 1104 1105 /* 1106 * Remove the loopback route to the interface address. --- 18 unchanged lines hidden (view full) --- 1125 (ia_ro.ro_rt->rt_ifp == V_loif)) { 1126 RT_LOCK(ia_ro.ro_rt); 1127 if (ia_ro.ro_rt->rt_refcnt <= 1) 1128 freeit = 1; 1129 else 1130 RT_REMREF(ia_ro.ro_rt); 1131 RTFREE_LOCKED(ia_ro.ro_rt); 1132 } | 1099{ 1100 struct in_ifaddr *ia; 1101 struct in_addr prefix, mask, p; 1102 int error = 0; 1103 struct sockaddr_in prefix0, mask0; 1104 1105 /* 1106 * Remove the loopback route to the interface address. --- 18 unchanged lines hidden (view full) --- 1125 (ia_ro.ro_rt->rt_ifp == V_loif)) { 1126 RT_LOCK(ia_ro.ro_rt); 1127 if (ia_ro.ro_rt->rt_refcnt <= 1) 1128 freeit = 1; 1129 else 1130 RT_REMREF(ia_ro.ro_rt); 1131 RTFREE_LOCKED(ia_ro.ro_rt); 1132 } |
1133 if (freeit) | 1133 if (freeit && (flags & LLE_STATIC)) { |
1134 error = ifa_del_loopback_route((struct ifaddr *)target, 1135 (struct sockaddr *)&target->ia_addr); | 1134 error = ifa_del_loopback_route((struct ifaddr *)target, 1135 (struct sockaddr *)&target->ia_addr); |
1136 if (error == 0) 1137 target->ia_flags &= ~IFA_RTSELF; 1138 /* remove arp cache */ 1139 arp_ifscrub(target->ia_ifp, IA_SIN(target)->sin_addr.s_addr); | 1136 if (error == 0) 1137 target->ia_flags &= ~IFA_RTSELF; 1138 } 1139 if (flags & LLE_STATIC) 1140 /* remove arp cache */ 1141 arp_ifscrub(target->ia_ifp, IA_SIN(target)->sin_addr.s_addr); |
1140 } 1141 1142 if (rtinitflags(target)) 1143 prefix = target->ia_dstaddr.sin_addr; 1144 else { 1145 prefix = target->ia_addr.sin_addr; 1146 mask = target->ia_sockmask.sin_addr; 1147 prefix.s_addr &= mask.s_addr; --- 50 unchanged lines hidden (view full) --- 1198 prefix0.sin_len = sizeof(prefix0); 1199 prefix0.sin_family = AF_INET; 1200 prefix0.sin_addr.s_addr = target->ia_subnet; 1201 bzero(&mask0, sizeof(mask0)); 1202 mask0.sin_len = sizeof(mask0); 1203 mask0.sin_family = AF_INET; 1204 mask0.sin_addr.s_addr = target->ia_subnetmask; 1205 lltable_prefix_free(AF_INET, (struct sockaddr *)&prefix0, | 1142 } 1143 1144 if (rtinitflags(target)) 1145 prefix = target->ia_dstaddr.sin_addr; 1146 else { 1147 prefix = target->ia_addr.sin_addr; 1148 mask = target->ia_sockmask.sin_addr; 1149 prefix.s_addr &= mask.s_addr; --- 50 unchanged lines hidden (view full) --- 1200 prefix0.sin_len = sizeof(prefix0); 1201 prefix0.sin_family = AF_INET; 1202 prefix0.sin_addr.s_addr = target->ia_subnet; 1203 bzero(&mask0, sizeof(mask0)); 1204 mask0.sin_len = sizeof(mask0); 1205 mask0.sin_family = AF_INET; 1206 mask0.sin_addr.s_addr = target->ia_subnetmask; 1207 lltable_prefix_free(AF_INET, (struct sockaddr *)&prefix0, |
1206 (struct sockaddr *)&mask0); | 1208 (struct sockaddr *)&mask0, flags); |
1207 1208 /* 1209 * As no-one seem to have this prefix, we can remove the route. 1210 */ 1211 rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target)); 1212 target->ia_flags &= ~IFA_ROUTE; 1213 return (0); 1214} --- 142 unchanged lines hidden (view full) --- 1357 1358 1359#define IN_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \ 1360 (((ntohl((d)->sin_addr.s_addr) ^ (a)->sin_addr.s_addr) & (m)->sin_addr.s_addr)) == 0 ) 1361 1362static void 1363in_lltable_prefix_free(struct lltable *llt, 1364 const struct sockaddr *prefix, | 1209 1210 /* 1211 * As no-one seem to have this prefix, we can remove the route. 1212 */ 1213 rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target)); 1214 target->ia_flags &= ~IFA_ROUTE; 1215 return (0); 1216} --- 142 unchanged lines hidden (view full) --- 1359 1360 1361#define IN_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \ 1362 (((ntohl((d)->sin_addr.s_addr) ^ (a)->sin_addr.s_addr) & (m)->sin_addr.s_addr)) == 0 ) 1363 1364static void 1365in_lltable_prefix_free(struct lltable *llt, 1366 const struct sockaddr *prefix, |
1365 const struct sockaddr *mask) | 1367 const struct sockaddr *mask, 1368 u_int flags) |
1366{ 1367 const struct sockaddr_in *pfx = (const struct sockaddr_in *)prefix; 1368 const struct sockaddr_in *msk = (const struct sockaddr_in *)mask; 1369 struct llentry *lle, *next; 1370 register int i; 1371 size_t pkts_dropped; 1372 1373 for (i=0; i < LLTBL_HASHTBL_SIZE; i++) { 1374 LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) { 1375 | 1369{ 1370 const struct sockaddr_in *pfx = (const struct sockaddr_in *)prefix; 1371 const struct sockaddr_in *msk = (const struct sockaddr_in *)mask; 1372 struct llentry *lle, *next; 1373 register int i; 1374 size_t pkts_dropped; 1375 1376 for (i=0; i < LLTBL_HASHTBL_SIZE; i++) { 1377 LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) { 1378 |
1379 /* 1380 * (flags & LLE_STATIC) means deleting all entries 1381 * including static ARP entries 1382 */ |
|
1376 if (IN_ARE_MASKED_ADDR_EQUAL((struct sockaddr_in *)L3_ADDR(lle), | 1383 if (IN_ARE_MASKED_ADDR_EQUAL((struct sockaddr_in *)L3_ADDR(lle), |
1377 pfx, msk)) { | 1384 pfx, msk) && 1385 ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC))) { |
1378 int canceled; 1379 1380 canceled = callout_drain(&lle->la_timer); 1381 LLE_WLOCK(lle); 1382 if (canceled) 1383 LLE_REMREF(lle); 1384 pkts_dropped = llentry_free(lle); 1385 ARPSTAT_ADD(dropped, pkts_dropped); --- 222 unchanged lines hidden --- | 1386 int canceled; 1387 1388 canceled = callout_drain(&lle->la_timer); 1389 LLE_WLOCK(lle); 1390 if (canceled) 1391 LLE_REMREF(lle); 1392 pkts_dropped = llentry_free(lle); 1393 ARPSTAT_ADD(dropped, pkts_dropped); --- 222 unchanged lines hidden --- |