svn commit: r273559 - in projects/routing/sys: net netinet
Alexander V. Chernikov
melifaro at FreeBSD.org
Thu Oct 23 21:09:16 UTC 2014
Author: melifaro
Date: Thu Oct 23 21:09:14 2014
New Revision: 273559
URL: https://svnweb.freebsd.org/changeset/base/273559
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 Thu Oct 23 21:02:40 2014 (r273558)
+++ projects/routing/sys/net/rt_nhops.c Thu Oct 23 21:09:14 2014 (r273559)
@@ -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 Thu Oct 23 21:02:40 2014 (r273558)
+++ projects/routing/sys/net/rt_nhops.h Thu Oct 23 21:09:14 2014 (r273559)
@@ -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 Thu Oct 23 21:02:40 2014 (r273558)
+++ projects/routing/sys/netinet/in_pcb.c Thu Oct 23 21:09:14 2014 (r273559)
@@ -91,6 +91,7 @@ __FBSDID("$FreeBSD$");
#include <netinet6/in6_var.h>
#include <netinet6/ip6_var.h>
#endif /* INET6 */
+#include <net/rt_nhops.h>
#ifdef IPSEC
@@ -750,8 +751,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__));
@@ -764,9 +767,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;
@@ -777,8 +779,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
@@ -788,7 +799,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;
@@ -844,23 +855,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;
}
@@ -869,7 +879,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;
@@ -902,7 +912,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;
@@ -963,8 +973,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 Thu Oct 23 21:02:40 2014 (r273558)
+++ projects/routing/sys/netinet/ip_output.c Thu Oct 23 21:09:14 2014 (r273559)
@@ -101,9 +101,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[];
@@ -672,7 +669,7 @@ passout:
*/
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;
}
@@ -709,7 +706,7 @@ passout:
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);
}
@@ -726,45 +723,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.
More information about the svn-src-projects
mailing list