Re: Implementing IP_SENDIF (like SO_BINDTODEVICE)

From: Julian Elischer (julian_at_elischer.org)
Date: 10/27/04

  • Next message: Bruce M Simpson: "Re: cvs commit: src/sys/netinet if_ether.c"
    Date: Wed, 27 Oct 2004 12:28:22 -0700
    To: Bruce M Simpson <bms@spc.org>
    
    

    Bruce M Simpson wrote:

    >It annoys me that we have to resort to BPF to send IP datagrams on
    >unnumbered interfaces. Here is a half baked idea. Please look and
    >tell me what you think.
    >

    I've sent lots of datagrams on un-numberred interfaces using netgraph..

    >
    >
    >------------------------------------------------------------------------
    >
    >Adding IP_SENDIF (like Linux's SO_BINDTODEVICE) support to FreeBSD.
    >Clean up the RFC 1724 hack in ip_output.c
    >
    >TODO:
    >
    >Add IP_SENDIF processing to ip_ctloutput.
    >Move inp_depend6.inp6_ifindex into general inpcb structure.
    >Update #define.
    >Pass IP_ROUTETOIF flag to ip_output() from udp and rawip.
    >Pass inp_ifindex to ip_output() as destination from udp and rawip.
    >
    >Index: src/sys/netinet/ip_output.c
    >===================================================================
    >RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v
    >retrieving revision 1.225.2.4
    >diff -u -p -r1.225.2.4 ip_output.c
    >--- src/sys/netinet/ip_output.c 22 Sep 2004 19:23:38 -0000 1.225.2.4
    >+++ src/sys/netinet/ip_output.c 27 Oct 2004 07:27:24 -0000
    >@@ -93,7 +93,7 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, mbuf_
    > #endif
    >
    > static struct mbuf *ip_insertoptions(struct mbuf *, struct mbuf *, int *);
    >-static struct ifnet *ip_multicast_if(struct in_addr *, int *);
    >+static struct ifnet *ina_to_rfc1724_if(struct in_addr *, int *);
    > static void ip_mloopback
    > (struct ifnet *, struct mbuf *, struct sockaddr_in *, int);
    > static int ip_getmoptions
    >@@ -206,19 +206,30 @@ again:
    > dst->sin_addr = ip->ip_dst;
    > }
    > /*
    >- * If routing to interface only,
    >- * short circuit routing lookup.
    >+ * If routing to interface only, short circuit routing lookup.
    >+ *
    >+ * Assume the destination is either the destination end of a
    >+ * point-to-point interface, the network address of an interface,
    >+ * or the address of an interface itself. In the last case, an
    >+ * interface may be specified by index as per RFC 1724.
    >+ *
    > */
    > if (flags & IP_ROUTETOIF) {
    >- if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == NULL &&
    >- (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == NULL) {
    >+ ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)));
    >+ if (ia == NULL)
    >+ ia = ifatoia(ifa_ifwithnet(sintosa(dst)));
    >+ if (ia != NULL)
    >+ ifp = ia->ia_ifp;
    >+ else
    >+ ifp = ina_to_rfc1724_if(&dst->sin_addr, NULL);
    >+ if (ifp == NULL) {
    > ipstat.ips_noroute++;
    > error = ENETUNREACH;
    > goto bad;
    > }
    >- ifp = ia->ia_ifp;
    > ip->ip_ttl = 1;
    >- isbroadcast = in_broadcast(dst->sin_addr, ifp);
    >+ isbroadcast = (flags & IP_SENDONES) |
    >+ in_broadcast(dst->sin_addr, ifp);
    > } else if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) &&
    > imo != NULL && imo->imo_multicast_ifp != NULL) {
    > /*
    >@@ -1531,11 +1542,15 @@ bad:
    > * standard option (IP_TTL).
    > */
    >
    >+#define INADDR_IFINDEX_MASK 0x00FFFFFF /* 0.0.0.0/8 */
    >+
    > /*
    >- * following RFC1724 section 3.3, 0.0.0.0/8 is interpreted as interface index.
    >+ * Look up the ifnet corresponding to a given IPv4 host address, taking the
    >+ * RFC1724 hack into account. If the address given has the network prefix
    >+ * 0.0.0.0/8, interpret the host portion as an interface index.
    > */
    > static struct ifnet *
    >-ip_multicast_if(a, ifindexp)
    >+ina_to_rfc1724_if(a, ifindexp)
    > struct in_addr *a;
    > int *ifindexp;
    > {
    >@@ -1544,8 +1559,8 @@ ip_multicast_if(a, ifindexp)
    >
    > if (ifindexp)
    > *ifindexp = 0;
    >- if (ntohl(a->s_addr) >> 24 == 0) {
    >- ifindex = ntohl(a->s_addr) & 0xffffff;
    >+ if ((ntohl(a->s_addr) & ~INADDR_IFINDEX_MASK) == 0) {
    >+ ifindex = ntohl(a->s_addr) & 0x00FFFFFF;
    > if (ifindex < 0 || if_index < ifindex)
    > return NULL;
    > ifp = ifnet_byindex(ifindex);
    >@@ -1554,7 +1569,7 @@ ip_multicast_if(a, ifindexp)
    > } else {
    > INADDR_TO_IFP(*a, ifp);
    > }
    >- return ifp;
    >+ return (ifp);
    > }
    >
    > /*
    >@@ -1634,7 +1649,7 @@ ip_setmoptions(sopt, imop)
    > * it supports multicasting.
    > */
    > s = splimp();
    >- ifp = ip_multicast_if(&addr, &ifindex);
    >+ ifp = ina_to_rfc1724_if(&addr, &ifindex);
    > if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
    > splx(s);
    > error = EADDRNOTAVAIL;
    >@@ -1731,7 +1746,7 @@ ip_setmoptions(sopt, imop)
    > RTFREE(ro.ro_rt);
    > }
    > else {
    >- ifp = ip_multicast_if(&mreq.imr_interface, NULL);
    >+ ifp = ina_to_rfc1724_if(&mreq.imr_interface, NULL);
    > }
    >
    > /*
    >@@ -1799,7 +1814,7 @@ ip_setmoptions(sopt, imop)
    > if (mreq.imr_interface.s_addr == INADDR_ANY)
    > ifp = NULL;
    > else {
    >- ifp = ip_multicast_if(&mreq.imr_interface, NULL);
    >+ ifp = ina_to_rfc1724_if(&mreq.imr_interface, NULL);
    > if (ifp == NULL) {
    > error = EADDRNOTAVAIL;
    > splx(s);
    >
    >

    _______________________________________________
    freebsd-net@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-net
    To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"


  • Next message: Bruce M Simpson: "Re: cvs commit: src/sys/netinet if_ether.c"

    Relevant Pages