On Mon, Dec 24, 2018 at 08:43:10PM -0200, Martin Pieuchot wrote:
> It would be great if you could think the IPv4 version as well to take
> a 'struct sockaddr' argument instead of a `struct in_ifaddr'.
> 

Here is a diff to convert "struct in_ifaddr" to "struct sockaddr"

Index: netinet/ip_icmp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_icmp.c,v
retrieving revision 1.181
diff -u -p -r1.181 ip_icmp.c
--- netinet/ip_icmp.c   28 Nov 2018 08:15:29 -0000      1.181
+++ netinet/ip_icmp.c   25 Dec 2018 20:11:37 -0000
@@ -676,11 +676,12 @@ freeit:
  * Reflect the ip packet back to the source
  */
 int
-icmp_reflect(struct mbuf *m, struct mbuf **op, struct in_ifaddr *ia)
+icmp_reflect(struct mbuf *m, struct mbuf **op, struct sockaddr *sa)
 {
        struct ip *ip = mtod(m, struct ip *);
        struct mbuf *opts = NULL;
        struct sockaddr_in sin;
+       struct in_ifaddr *ia = NULL;
        struct rtentry *rt = NULL;
        int optlen = (ip->ip_hl << 2) - sizeof(struct ip);
        u_int rtableid;
@@ -700,12 +701,18 @@ icmp_reflect(struct mbuf *m, struct mbuf
        m_resethdr(m);
        m->m_pkthdr.ph_rtableid = rtableid;
 
+       if (sa != NULL) {
+               rt = rtalloc(sa, RT_RESOLVE, rtableid);
+               if (rtisvalid(rt) && rt->rt_ifa->ifa_addr->sa_family == AF_INET)
+                       ia = ifatoia(rt->rt_ifa);
+       }
        /*
         * If the incoming packet was addressed directly to us,
         * use dst as the src for the reply.  For broadcast, use
         * the address which corresponds to the incoming interface.
         */
        if (ia == NULL) {
+               rtfree(rt);
                memset(&sin, 0, sizeof(sin));
                sin.sin_len = sizeof(sin);
                sin.sin_family = AF_INET;
@@ -732,7 +739,7 @@ icmp_reflect(struct mbuf *m, struct mbuf
 
                /* keep packet in the original virtual instance */
                rt = rtalloc(sintosa(&sin), RT_RESOLVE, rtableid);
-               if (rt == NULL) {
+               if (!rtisvalid(rt)) {
                        ipstat_inc(ips_noroute);
                        m_freem(m);
                        return (EHOSTUNREACH);
Index: netinet/ip_icmp.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_icmp.h,v
retrieving revision 1.31
diff -u -p -r1.31 ip_icmp.h
--- netinet/ip_icmp.h   5 Nov 2018 21:50:39 -0000       1.31
+++ netinet/ip_icmp.h   25 Dec 2018 20:11:37 -0000
@@ -235,7 +235,7 @@ struct mbuf *
 void   icmp_error(struct mbuf *, int, int, u_int32_t, int);
 int    icmp_input(struct mbuf **, int *, int, int);
 void   icmp_init(void);
-int    icmp_reflect(struct mbuf *, struct mbuf **, struct in_ifaddr *);
+int    icmp_reflect(struct mbuf *, struct mbuf **, struct sockaddr *);
 void   icmp_send(struct mbuf *, struct mbuf *);
 int    icmp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
 struct rtentry *
Index: netmpls/mpls_input.c
===================================================================
RCS file: /cvs/src/sys/netmpls/mpls_input.c,v
retrieving revision 1.68
diff -u -p -r1.68 mpls_input.c
--- netmpls/mpls_input.c        12 Jan 2018 06:57:56 -0000      1.68
+++ netmpls/mpls_input.c        25 Dec 2018 20:11:37 -0000
@@ -339,9 +339,7 @@ mpls_do_error(struct mbuf *m, int type, 
        struct shim_hdr stack[MPLS_INKERNEL_LOOP_MAX];
        struct sockaddr_mpls sa_mpls;
        struct sockaddr_mpls *smpls;
-       struct rtentry *rt = NULL;
        struct shim_hdr *shim;
-       struct in_ifaddr *ia;
        struct icmp *icp;
        struct ip *ip;
        int nstk, error;
@@ -380,26 +378,7 @@ mpls_do_error(struct mbuf *m, int type, 
                smpls->smpls_len = sizeof(*smpls);
                smpls->smpls_label = shim->shim_label & MPLS_LABEL_MASK;
 
-               rt = rtalloc(smplstosa(smpls), RT_RESOLVE, 0);
-               if (rt == NULL) {
-                       /* no entry for this label */
-                       m_freem(m);
-                       return (NULL);
-               }
-               if (rt->rt_ifa->ifa_addr->sa_family == AF_INET)
-                       ia = ifatoia(rt->rt_ifa);
-               else {
-                       /* XXX this needs fixing, if the MPLS is on an IP
-                        * less interface we need to find some other IP to
-                        * use as source.
-                        */
-                       rtfree(rt);
-                       m_freem(m);
-                       return (NULL);
-               }
-               /* It is safe to dereference ``ia'' iff ``rt'' is valid. */
-               error = icmp_reflect(m, NULL, ia);
-               rtfree(rt);
+               error = icmp_reflect(m, NULL, smplstosa(smpls));
                if (error)
                        return (NULL);
 

Reply via email to