Deleted Added
full compact
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 ---