diff options
author | melifaro <melifaro@FreeBSD.org> | 2014-05-08 21:03:31 +0000 |
---|---|---|
committer | melifaro <melifaro@FreeBSD.org> | 2014-05-08 21:03:31 +0000 |
commit | aaa6b80bb3815234e2f1d109c77aa0b2d08b0c97 (patch) | |
tree | de4f158e6da3ea5d7a35c686cb4981bd6c2aa95c /sys/netinet/in.c | |
parent | 1085179b784bd3c6855a3d1144933dbe8ed5e757 (diff) | |
download | FreeBSD-src-aaa6b80bb3815234e2f1d109c77aa0b2d08b0c97.zip FreeBSD-src-aaa6b80bb3815234e2f1d109c77aa0b2d08b0c97.tar.gz |
Merge 260488, r260508.
r260488:
Split rt_newaddrmsg_fib() into two different functions.
Adding/deleting interface addresses involves access to 3 different subsystems,
int different parts of code. Each call can fail, so reporting successful
operation by rtsock in the middle of the process error-prone.
Further split routing notification API and actual rtsock calls via creating
public-available rt_addrmsg() / rt_routemsg() functions with "private"
rtsock_* backend.
r260508:
Simplify inet alias handling code: if we're adding/removing alias which
has the same prefix as some other alias on the same interface, use
newly-added rt_addrmsg() instead of hand-rolled in_addralias_rtmsg().
This eliminates the following rtsock messages:
Pinned RTM_ADD for prefix (for alias addition).
Pinned RTM_DELETE for prefix (for alias withdrawal).
Example (got 10.0.0.1/24 on vlan4, playing with 10.0.0.2/24):
before commit, addition:
got message of size 116 on Fri Jan 10 14:13:15 2014
RTM_NEWADDR: address being added to iface: len 116, metric 0, flags:
sockaddrs: <NETMASK,IFP,IFA,BRD>
255.255.255.0 vlan4:8.0.27.c5.29.d4 10.0.0.2 10.0.0.255
got message of size 192 on Fri Jan 10 14:13:15 2014
RTM_ADD: Add Route: len 192, pid: 0, seq 0, errno 0, flags:<UP,PINNED>
locks: inits:
sockaddrs: <DST,GATEWAY,NETMASK>
10.0.0.0 10.0.0.2 (255) ffff ffff ff
after commit, addition:
got message of size 116 on Fri Jan 10 13:56:26 2014
RTM_NEWADDR: address being added to iface: len 116, metric 0, flags:
sockaddrs: <NETMASK,IFP,IFA,BRD>
255.255.255.0 vlan4:8.0.27.c5.29.d4 14.0.0.2 14.0.0.255
before commit, wihdrawal:
got message of size 192 on Fri Jan 10 13:58:59 2014
RTM_DELETE: Delete Route: len 192, pid: 0, seq 0, errno 0, flags:<UP,PINNED>
locks: inits:
sockaddrs: <DST,GATEWAY,NETMASK>
10.0.0.0 10.0.0.2 (255) ffff ffff ff
got message of size 116 on Fri Jan 10 13:58:59 2014
RTM_DELADDR: address being removed from iface: len 116, metric 0, flags:
sockaddrs: <NETMASK,IFP,IFA,BRD>
255.255.255.0 vlan4:8.0.27.c5.29.d4 10.0.0.2 10.0.0.255
adter commit, withdrawal:
got message of size 116 on Fri Jan 10 14:14:11 2014
RTM_DELADDR: address being removed from iface: len 116, metric 0, flags:
sockaddrs: <NETMASK,IFP,IFA,BRD>
255.255.255.0 vlan4:8.0.27.c5.29.d4 10.0.0.2 10.0.0.255
Sending both RTM_ADD/RTM_DELETE messages to rtsock is completely wrong
(and requires some hacks to keep prefix in route table on RTM_DELETE).
I've tested this change with quagga (no change) and bird (*).
bird alias handling is already broken in *BSD sysdep code, so nothing
changes here, too.
I'm going to MFC this change if there will be no complains about behavior
change.
While here, fix some style(9) bugs introduced by r260488
(pointed by glebius and bde).
Diffstat (limited to 'sys/netinet/in.c')
-rw-r--r-- | sys/netinet/in.c | 51 |
1 files changed, 8 insertions, 43 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c index f85b14f..4cc9d22 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -901,45 +901,6 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, ? RTF_HOST : 0) /* - * Generate a routing message when inserting or deleting - * an interface address alias. - */ -static void in_addralias_rtmsg(int cmd, struct in_addr *prefix, - struct in_ifaddr *target) -{ - struct route pfx_ro; - struct sockaddr_in *pfx_addr; - struct rtentry msg_rt; - - /* QL: XXX - * This is a bit questionable because there is no - * additional route entry added/deleted for an address - * alias. Therefore this route report is inaccurate. - */ - bzero(&pfx_ro, sizeof(pfx_ro)); - pfx_addr = (struct sockaddr_in *)(&pfx_ro.ro_dst); - pfx_addr->sin_len = sizeof(*pfx_addr); - pfx_addr->sin_family = AF_INET; - pfx_addr->sin_addr = *prefix; - rtalloc_ign_fib(&pfx_ro, 0, 0); - if (pfx_ro.ro_rt != NULL) { - msg_rt = *pfx_ro.ro_rt; - - /* QL: XXX - * Point the gateway to the new interface - * address as if a new prefix route entry has - * been added through the new address alias. - * All other parts of the rtentry is accurate, - * e.g., rt_key, rt_mask, rt_ifp etc. - */ - msg_rt.rt_gateway = (struct sockaddr *)&target->ia_addr; - rt_newaddrmsg(cmd, (struct ifaddr *)target, 0, &msg_rt); - RTFREE(pfx_ro.ro_rt); - } - return; -} - -/* * Check if we have a route for the given prefix already or add one accordingly. */ int @@ -947,7 +908,7 @@ in_addprefix(struct in_ifaddr *target, int flags) { struct in_ifaddr *ia; struct in_addr prefix, mask, p, m; - int error; + int error, fibnum; if ((flags & RTF_HOST) != 0) { prefix = target->ia_dstaddr.sin_addr; @@ -958,6 +919,8 @@ in_addprefix(struct in_ifaddr *target, int flags) prefix.s_addr &= mask.s_addr; } + fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib; + IN_IFADDR_RLOCK(); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if (rtinitflags(ia)) { @@ -992,7 +955,7 @@ in_addprefix(struct in_ifaddr *target, int flags) IN_IFADDR_RUNLOCK(); return (EEXIST); } else { - in_addralias_rtmsg(RTM_ADD, &prefix, target); + rt_addrmsg(RTM_ADD, &target->ia_ifa, fibnum); IN_IFADDR_RUNLOCK(); return (0); } @@ -1019,9 +982,11 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) { struct in_ifaddr *ia; struct in_addr prefix, mask, p, m; - int error = 0; + int error = 0, fibnum; struct sockaddr_in prefix0, mask0; + fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib; + /* * Remove the loopback route to the interface address. * The "useloopback" setting is not consulted because if the @@ -1074,7 +1039,7 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) } if ((target->ia_flags & IFA_ROUTE) == 0) { - in_addralias_rtmsg(RTM_DELETE, &prefix, target); + rt_addrmsg(RTM_DELETE, &target->ia_ifa, fibnum); return (0); } |