Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F159198450
D28246.id82595.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D28246.id82595.diff
View Options
Index: sys/netinet/in.c
===================================================================
--- sys/netinet/in.c
+++ sys/netinet/in.c
@@ -79,6 +79,8 @@
static void in_socktrim(struct sockaddr_in *);
static void in_purgemaddrs(struct ifnet *);
+static bool ia_need_loopback_route(const struct in_ifaddr *);
+
VNET_DEFINE_STATIC(int, nosameprefix);
#define V_nosameprefix VNET(nosameprefix)
SYSCTL_INT(_net_inet_ip, OID_AUTO, no_same_prefix, CTLFLAG_VNET | CTLFLAG_RW,
@@ -494,10 +496,7 @@
/*
* Add a loopback route to self.
*/
- if (vhid == 0 && (ifp->if_flags & IFF_LOOPBACK) == 0 &&
- ia->ia_addr.sin_addr.s_addr != INADDR_ANY &&
- !((ifp->if_flags & IFF_POINTOPOINT) &&
- ia->ia_dstaddr.sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr)) {
+ if (vhid == 0 && ia_need_loopback_route(ia)) {
struct in_ifaddr *eia;
eia = in_localip_more(ia);
@@ -723,7 +722,8 @@
static int
in_handle_prefix_route(uint32_t fibnum, int cmd,
- struct sockaddr_in *dst, struct sockaddr_in *netmask, struct ifaddr *ifa)
+ struct sockaddr_in *dst, struct sockaddr_in *netmask, struct ifaddr *ifa,
+ struct ifnet *ifp)
{
NET_EPOCH_ASSERT();
@@ -738,6 +738,7 @@
struct rt_addrinfo info = {
.rti_ifa = ifa,
+ .rti_ifp = ifp,
.rti_flags = RTF_PINNED | ((netmask != NULL) ? 0 : RTF_HOST),
.rti_info = {
[RTAX_DST] = (struct sockaddr *)dst,
@@ -752,6 +753,55 @@
return (rib_handle_ifaddr_info(fibnum, cmd, &info));
}
+static void
+ia_getrtprefix(const struct in_ifaddr *ia, struct in_addr *prefix, struct in_addr *mask)
+{
+
+ if (ia->ia_ifp->if_flags & IFF_POINTOPOINT) {
+ *prefix = ia->ia_dstaddr.sin_addr;
+ mask->s_addr = INADDR_BROADCAST;
+ } else if (ia->ia_ifp->if_flags & IFF_LOOPBACK) {
+ *prefix = ia->ia_addr.sin_addr;
+ mask->s_addr = INADDR_BROADCAST;
+ } else {
+ *prefix = ia->ia_addr.sin_addr;
+ *mask = ia->ia_sockmask.sin_addr;
+ prefix->s_addr &= mask->s_addr;
+ }
+}
+
+/*
+ * Checks if @ia needs to have loopback route installed.
+ *
+ * Skip loopback interfaces - prefix route will be installed by
+ * in_handle_ifaddr_route().
+ * Skip p2p interfaces with both addresses are equal
+ * Skip empty addresses.
+ * Skip /32 masks - prefix will be installed by in_handle_ifaddr_route().
+ *
+ * Return true on success.
+ */
+static bool
+ia_need_loopback_route(const struct in_ifaddr *ia)
+{
+ struct ifnet *ifp = ia->ia_ifp;
+
+ if ((ifp->if_flags & IFF_LOOPBACK) ||
+ (ia->ia_addr.sin_addr.s_addr == INADDR_ANY))
+ return (false);
+
+ if ((ifp->if_flags & IFF_POINTOPOINT) &&
+ ia->ia_dstaddr.sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr)
+ return (false);
+
+ if (!(ifp->if_flags & IFF_POINTOPOINT) &&
+ (ia->ia_sockmask.sin_addr.s_addr == INADDR_BROADCAST))
+ return (false);
+
+ return (true);
+}
+
+
/*
* Adds or delete interface route corresponding to @ifa.
* There can be multiple options:
@@ -760,10 +810,8 @@
* 192.0.2.0/24 via this interface, using ifa as an address source.
* Note: route to 192.0.2.1 will be installed separately via
* ifa_maintain_loopback_route().
- * 2) Adding addr with "host" mask.
- * Example: 192.0.2.2/32. In this case no action is performed,
- * as the route should be installed by ifa_maintain_loopback_route().
- * Returns 0 to indicate success.
+ * 2) Adding addr with "host" mask to non-p2p interface.
+ * Example: 192.0.2.2/32. Action: add host route via loopback interface.
* 3) Adding address with or without prefix to p2p interface.
* Example: 10.0.0.1/24->10.0.0.2. In this case, all other addresses
* covered by prefix, does not make sense in the context of p2p link.
@@ -774,8 +822,10 @@
* 4) Adding address with or without prefix to loopback interface.
* Example: 192.0.2.1/24. In this case, trafic to non-host addresses cannot
* be forwarded, as it would introduce an infinite cycle.
- * Similar to (2), perform no action and return 0. Loopback route
- * will be installed by ifa_maintain_loopback_route().
+ * Action: install host route via ifa interface, using ia as an
+ * address source.
+ *
+ * Returns 0 on success or errno.
*/
int
in_handle_ifaddr_route(int cmd, struct in_ifaddr *ia)
@@ -786,25 +836,7 @@
struct epoch_tracker et;
int error;
- /* Case 4: ignore loopbacks */
- if (ifa->ifa_ifp->if_flags & IFF_LOOPBACK)
- return (0);
-
- if (ifa->ifa_ifp->if_flags & IFF_POINTOPOINT) {
- /* Case 3: install route towards dst addr */
- daddr = ia->ia_dstaddr.sin_addr;
- pmask = NULL;
- maddr.s_addr = INADDR_BROADCAST;
- } else {
- daddr = ia->ia_addr.sin_addr;
- pmask = &ia->ia_sockmask;
- maddr = pmask->sin_addr;
-
- if (maddr.s_addr == INADDR_BROADCAST) {
- /* Case 2: ignore /32 routes */
- return (0);
- }
- }
+ ia_getrtprefix(ia, &daddr, &maddr);
struct sockaddr_in mask = {
.sin_family = AF_INET,
@@ -812,8 +844,7 @@
.sin_addr = maddr,
};
- if (pmask != NULL)
- pmask = &mask;
+ pmask = (maddr.s_addr != INADDR_BROADCAST) ? &mask : NULL;
struct sockaddr_in dst = {
.sin_family = AF_INET,
@@ -821,56 +852,45 @@
.sin_addr.s_addr = daddr.s_addr & maddr.s_addr,
};
+ struct ifnet *ifp = ia->ia_ifp;
+
+ if ((maddr.s_addr == INADDR_BROADCAST) &&
+ (!(ia->ia_ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)))) {
+ /* Case 2: host route on broadcast interface */
+ ifp = V_loif;
+ }
+
uint32_t fibnum = ifa->ifa_ifp->if_fib;
NET_EPOCH_ENTER(et);
- error = in_handle_prefix_route(fibnum, cmd, &dst, pmask, ifa);
+ error = in_handle_prefix_route(fibnum, cmd, &dst, pmask, ifa, ifp);
NET_EPOCH_EXIT(et);
return (error);
}
-#define rtinitflags(x) \
- ((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \
- ? RTF_HOST : 0)
-
/*
* Check if we have a route for the given prefix already.
*/
static bool
-in_hasrtprefix(struct in_ifaddr *target, int flags)
+in_hasrtprefix(struct in_ifaddr *target)
{
struct rm_priotracker in_ifa_tracker;
struct in_ifaddr *ia;
struct in_addr prefix, mask, p, m;
bool result = false;
- if ((flags & RTF_HOST) != 0) {
- prefix = target->ia_dstaddr.sin_addr;
- mask.s_addr = 0;
- } else {
- prefix = target->ia_addr.sin_addr;
- mask = target->ia_sockmask.sin_addr;
- prefix.s_addr &= mask.s_addr;
- }
+ ia_getrtprefix(target, &prefix, &mask);
IN_IFADDR_RLOCK(&in_ifa_tracker);
/* Look for an existing address with the same prefix, mask, and fib */
CK_STAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
- if (rtinitflags(ia)) {
- p = ia->ia_dstaddr.sin_addr;
+ ia_getrtprefix(ia, &p, &m);
- if (prefix.s_addr != p.s_addr)
- continue;
- } else {
- p = ia->ia_addr.sin_addr;
- m = ia->ia_sockmask.sin_addr;
- p.s_addr &= m.s_addr;
+ if (prefix.s_addr != p.s_addr ||
+ mask.s_addr != m.s_addr)
+ continue;
- if (prefix.s_addr != p.s_addr ||
- mask.s_addr != m.s_addr)
- continue;
- }
if (target->ia_ifp->if_fib != ia->ia_ifp->if_fib)
continue;
@@ -889,11 +909,11 @@
}
int
-in_addprefix(struct in_ifaddr *target, int flags)
+in_addprefix(struct in_ifaddr *target, int _unused)
{
int error;
- if (in_hasrtprefix(target, flags)) {
+ if (in_hasrtprefix(target)) {
if (V_nosameprefix)
return (EEXIST);
else {
@@ -967,9 +987,7 @@
/*
* Remove the loopback route to the interface address.
*/
- if ((target->ia_addr.sin_addr.s_addr != INADDR_ANY) &&
- !(target->ia_ifp->if_flags & IFF_LOOPBACK) &&
- (flags & LLE_STATIC)) {
+ if (ia_need_loopback_route(target) && (flags & LLE_STATIC)) {
struct in_ifaddr *eia;
/*
@@ -989,14 +1007,7 @@
}
}
- if (rtinitflags(target)) {
- prefix = target->ia_dstaddr.sin_addr;
- mask.s_addr = 0;
- } else {
- prefix = target->ia_addr.sin_addr;
- mask = target->ia_sockmask.sin_addr;
- prefix.s_addr &= mask.s_addr;
- }
+ ia_getrtprefix(target, &prefix, &mask);
if ((target->ia_flags & IFA_ROUTE) == 0) {
rt_addrmsg(RTM_DELETE, &target->ia_ifa, target->ia_ifp->if_fib);
@@ -1013,20 +1024,11 @@
IN_IFADDR_RLOCK(&in_ifa_tracker);
CK_STAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
- if (rtinitflags(ia)) {
- p = ia->ia_dstaddr.sin_addr;
-
- if (prefix.s_addr != p.s_addr)
- continue;
- } else {
- p = ia->ia_addr.sin_addr;
- m = ia->ia_sockmask.sin_addr;
- p.s_addr &= m.s_addr;
+ ia_getrtprefix(ia, &p, &m);
- if (prefix.s_addr != p.s_addr ||
- mask.s_addr != m.s_addr)
- continue;
- }
+ if (prefix.s_addr != p.s_addr ||
+ mask.s_addr != m.s_addr)
+ continue;
if ((ia->ia_ifp->if_flags & IFF_UP) == 0)
continue;
@@ -1077,8 +1079,6 @@
return (error);
}
-#undef rtinitflags
-
void
in_ifscrub_all(void)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jun 12, 5:43 AM (9 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33900711
Default Alt Text
D28246.id82595.diff (8 KB)
Attached To
Mode
D28246: Further refactor IPv4 interface route creation.
Attached
Detach File
Event Timeline
Log In to Comment