Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Aug 2015 18:15:19 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r287047 - in projects/routing/sys: net netinet
Message-ID:  <201508231815.t7NIFJ1U042238@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Sun Aug 23 18:15:18 2015
New Revision: 287047
URL: https://svnweb.freebsd.org/changeset/base/287047

Log:
  Rename ip_sendmbuf to fib4_sendmbuf() and move it to
   rt_nhops api. Convert IPv4 SAS to use new routing api.

Modified:
  projects/routing/sys/net/rt_nhops.c
  projects/routing/sys/net/rt_nhops.h
  projects/routing/sys/netinet/in_pcb.c
  projects/routing/sys/netinet/ip_output.c

Modified: projects/routing/sys/net/rt_nhops.c
==============================================================================
--- projects/routing/sys/net/rt_nhops.c	Sun Aug 23 18:14:30 2015	(r287046)
+++ projects/routing/sys/net/rt_nhops.c	Sun Aug 23 18:15:18 2015	(r287047)
@@ -315,7 +315,8 @@ fib4_lookup_prepend(uint32_t fibnum, str
 		 * It should be already presented if we're
 		 * sending data via known gateway.
 		 */
-		error = arpresolve_fast(lifp, gw, m->m_flags, eh->ether_dhost);
+		error = arpresolve_fast(lifp, gw, m ? m->m_flags : 0,
+		    eh->ether_dhost);
 		if (error == 0) {
 			memcpy(&eh->ether_shost, IF_LLADDR(lifp), ETHER_ADDR_LEN);
 			eh->ether_type = htons(ETHERTYPE_IP);
@@ -332,6 +333,46 @@ fib4_lookup_prepend(uint32_t fibnum, str
 	return (0);
 }
 
+int
+fib4_sendmbuf(struct ifnet *ifp, struct mbuf *m, struct nhop_data *nh,
+    struct in_addr dst)
+{
+	int error;
+
+	if (nh != NULL && (nh->nh_flags & NH_FLAGS_L2_INCOMPLETE) == 0) {
+
+		/*
+		 * Fast path case. Most packets should
+		 * be sent from here.
+		 * TODO: Make special ifnet
+		 * 'if_output_frame' handler for that.
+		 */
+		struct route_compat rc;
+		struct ether_header *eh;
+		rc.ro_flags = AF_INET << 8 | RT_NHOP;
+		rc.ro_nh = nh;
+
+		M_PREPEND(m, nh->nh_count, M_NOWAIT);
+		if (m == NULL)
+			return (ENOBUFS);
+		eh = mtod(m, struct ether_header *);
+		memcpy(eh, nh->d.data, nh->nh_count);
+		error = (*ifp->if_output)(ifp, m,
+		    NULL, (struct route *)&rc);
+	} else {
+		struct sockaddr_in gw_out;
+		memset(&gw_out, 0, sizeof(gw_out));
+		gw_out.sin_len = sizeof(gw_out);
+		gw_out.sin_family = AF_INET;
+		gw_out.sin_addr = nh ? nh->d.gw4 : dst;
+		error = (*ifp->if_output)(ifp, m,
+		    (const struct sockaddr *)&gw_out, NULL);
+	}
+
+	return (error);
+}
+
+
 static void
 fib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst,
     struct nhop4_extended *pnh4)

Modified: projects/routing/sys/net/rt_nhops.h
==============================================================================
--- projects/routing/sys/net/rt_nhops.h	Sun Aug 23 18:14:30 2015	(r287046)
+++ projects/routing/sys/net/rt_nhops.h	Sun Aug 23 18:15:18 2015	(r287047)
@@ -198,6 +198,9 @@ void fib4_choose_prepend(uint32_t fibnum
 int fib4_lookup_prepend(uint32_t fibnum, struct in_addr dst, struct mbuf *m,
     struct nhop_data *nh, struct nhop4_extended *nh_ext);
 
+int fib4_sendmbuf(struct ifnet *ifp, struct mbuf *m, struct nhop_data *nh,
+    struct in_addr dst);
+
 void fib6_free_nh(uint32_t fibnum, struct nhop_data *nh);
 void fib6_choose_prepend(uint32_t fibnum, struct nhop_data *nh_src,
     uint32_t flowid, struct nhop_data *nh, struct nhop6_extended *nh_ext);

Modified: projects/routing/sys/netinet/in_pcb.c
==============================================================================
--- projects/routing/sys/netinet/in_pcb.c	Sun Aug 23 18:14:30 2015	(r287046)
+++ projects/routing/sys/netinet/in_pcb.c	Sun Aug 23 18:15:18 2015	(r287047)
@@ -93,6 +93,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet6/in6_var.h>
 #include <netinet6/ip6_var.h>
 #endif /* INET6 */
+#include <net/rt_nhops.h>
 
 
 #ifdef IPSEC
@@ -756,8 +757,10 @@ in_pcbladdr(struct inpcb *inp, struct in
 {
 	struct ifaddr *ifa;
 	struct sockaddr *sa;
-	struct sockaddr_in *sin;
-	struct route sro;
+	struct sockaddr_in *sin, sin_storage;
+	struct nhop_data nhd, *pnhd;
+	struct nhop4_extended nh_ext;
+	u_int fibnum;
 	int error;
 
 	KASSERT(laddr != NULL, ("%s: laddr NULL", __func__));
@@ -770,9 +773,8 @@ in_pcbladdr(struct inpcb *inp, struct in
 		return (0);
 
 	error = 0;
-	bzero(&sro, sizeof(sro));
 
-	sin = (struct sockaddr_in *)&sro.ro_dst;
+	sin = &sin_storage;
 	sin->sin_family = AF_INET;
 	sin->sin_len = sizeof(struct sockaddr_in);
 	sin->sin_addr.s_addr = faddr->s_addr;
@@ -783,8 +785,17 @@ in_pcbladdr(struct inpcb *inp, struct in
 	 *
 	 * Find out route to destination.
 	 */
+	fibnum = inp->inp_inc.inc_fibnum;
+	pnhd = &nhd;
+	memset(&nhd, 0, sizeof(nhd));
+	memset(&nh_ext, 0, sizeof(nh_ext));
 	if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0)
-		in_rtalloc_ign(&sro, 0, inp->inp_inc.inc_fibnum);
+		error = fib4_lookup_prepend(fibnum, *faddr,
+		    NULL, &nhd, &nh_ext);
+	if (error != 0) {
+		pnhd = NULL;
+		error = 0;
+	}
 
 	/*
 	 * If we found a route, use the address corresponding to
@@ -794,7 +805,7 @@ in_pcbladdr(struct inpcb *inp, struct in
 	 * network and try to find a corresponding interface to take
 	 * the source address from.
 	 */
-	if (sro.ro_rt == NULL || sro.ro_rt->rt_ifp == NULL) {
+	if (pnhd == NULL) {
 		struct in_ifaddr *ia;
 		struct ifnet *ifp;
 
@@ -850,23 +861,22 @@ in_pcbladdr(struct inpcb *inp, struct in
 	 *    belonging to this jail. If so use it.
 	 * 3. as a last resort return the 'default' jail address.
 	 */
-	if ((sro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) {
+	if ((nh_ext.nh_ifp->if_flags & IFF_LOOPBACK) == 0) {
 		struct in_ifaddr *ia;
 		struct ifnet *ifp;
+		struct in_addr addr;
 
 		/* If not jailed, use the default returned. */
 		if (cred == NULL || !prison_flag(cred, PR_IP4)) {
-			ia = (struct in_ifaddr *)sro.ro_rt->rt_ifa;
-			laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
+			laddr->s_addr = nh_ext.nh_src.s_addr;
 			goto done;
 		}
 
 		/* Jailed. */
 		/* 1. Check if the iface address belongs to the jail. */
-		sin = (struct sockaddr_in *)sro.ro_rt->rt_ifa->ifa_addr;
-		if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
-			ia = (struct in_ifaddr *)sro.ro_rt->rt_ifa;
-			laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
+		addr = nh_ext.nh_src;
+		if (prison_check_ip4(cred, &addr) == 0) {
+			laddr->s_addr = nh_ext.nh_src.s_addr;
 			goto done;
 		}
 
@@ -875,7 +885,7 @@ in_pcbladdr(struct inpcb *inp, struct in
 		 *    belonging to this jail.
 		 */
 		ia = NULL;
-		ifp = sro.ro_rt->rt_ifp;
+		ifp = nh_ext.nh_ifp;
 		IF_ADDR_RLOCK(ifp);
 		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
 			sa = ifa->ifa_addr;
@@ -908,7 +918,7 @@ in_pcbladdr(struct inpcb *inp, struct in
 	 * In case of jails, check that it is an address of the jail
 	 * and if we cannot find, fall back to the 'default' jail address.
 	 */
-	if ((sro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
+	if ((nh_ext.nh_ifp->if_flags & IFF_LOOPBACK) != 0) {
 		struct sockaddr_in sain;
 		struct in_ifaddr *ia;
 
@@ -969,8 +979,8 @@ in_pcbladdr(struct inpcb *inp, struct in
 	}
 
 done:
-	if (sro.ro_rt != NULL)
-		RTFREE(sro.ro_rt);
+	if (pnhd != NULL)
+		fib4_free_nh(fibnum, pnhd);
 	return (error);
 }
 

Modified: projects/routing/sys/netinet/ip_output.c
==============================================================================
--- projects/routing/sys/netinet/ip_output.c	Sun Aug 23 18:14:30 2015	(r287046)
+++ projects/routing/sys/netinet/ip_output.c	Sun Aug 23 18:15:18 2015	(r287047)
@@ -102,9 +102,6 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, mbuf_
 #endif
 
 static void ip_mloopback (struct ifnet *, struct mbuf *, int);
-static inline int ip_sendmbuf(struct ifnet *ifp, struct mbuf *m,
-    struct nhop_data *nh, struct in_addr dst);
-
 
 extern int in_mcast_loop;
 extern	struct protosw inetsw[];
@@ -651,7 +648,7 @@ sendit:
 		 */
 		m_clrprotoflags(m);
 		IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
-		error = ip_sendmbuf(ifp, m, nh, dst);
+		error = fib4_sendmbuf(ifp, m, nh, dst);
 		goto done;
 	}
 
@@ -688,7 +685,7 @@ sendit:
 			m_clrprotoflags(m);
 
 			IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
-			error = ip_sendmbuf(ifp, m, nh, dst);
+			error = fib4_sendmbuf(ifp, m, nh, dst);
 		} else
 			m_freem(m);
 	}
@@ -706,45 +703,6 @@ bad:
 	goto done;
 }
 
-static inline int
-ip_sendmbuf(struct ifnet *ifp, struct mbuf *m, struct nhop_data *nh,
-    struct in_addr dst)
-{
-	int error;
-
-	if (nh != NULL && (nh->nh_flags & NH_FLAGS_L2_INCOMPLETE) == 0) {
-
-		/*
-		 * Fast path case. Most packets should
-		 * be sent from here.
-		 * TODO: Make special ifnet
-		 * 'if_output_frame' handler for that.
-		 */
-		struct route_compat rc;
-		struct ether_header *eh;
-		rc.ro_flags = AF_INET << 8 | RT_NHOP;
-		rc.ro_nh = nh;
-
-		M_PREPEND(m, nh->nh_count, M_NOWAIT);
-		if (m == NULL)
-			return (ENOBUFS);
-		eh = mtod(m, struct ether_header *);
-		memcpy(eh, nh->d.data, nh->nh_count);
-		error = (*ifp->if_output)(ifp, m,
-		    NULL, (struct route *)&rc);
-	} else {
-		struct sockaddr_in gw_out;
-		memset(&gw_out, 0, sizeof(gw_out));
-		gw_out.sin_len = sizeof(gw_out);
-		gw_out.sin_family = AF_INET;
-		gw_out.sin_addr = nh ? nh->d.gw4 : dst;
-		error = (*ifp->if_output)(ifp, m,
-		    (const struct sockaddr *)&gw_out, NULL);
-	}
-
-	return (error);
-}
-
 /*
  * Create a chain of fragments which fit the given mtu. m_frag points to the
  * mbuf to be fragmented; on return it points to the chain with the fragments.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508231815.t7NIFJ1U042238>