On Fri, Aug 23, 2019 at 10:05:25AM -0500, Gerrie Roos wrote:
> Hi David,
> 
> Apologies, I haven't used CVS in a while - here you go. Hope it's useful.
> 
> Gerrie

npz, i can read the attachment fine.

if someone's carrying a non-ip payload over mpls with a nibble that
makes it look like ip, your diff will cause (very) short payloads
to be dropped when m_pullup can't find bytes to copy into the first
mbuf.

could you try the following? it uses m_getptr to reach into the right
mbuf and byte offset in that mbuf for the ttl. if the packet is
short, it just returns the default ttl.

i've attached the diff for your convenience too.

cheers,
dlg

Index: mpls_output.c
===================================================================
RCS file: /cvs/src/sys/netmpls/mpls_output.c,v
retrieving revision 1.26
diff -u -p -r1.26 mpls_output.c
--- mpls_output.c       2 Dec 2015 08:47:00 -0000       1.26
+++ mpls_output.c       26 Aug 2019 09:11:08 -0000
@@ -162,41 +162,39 @@ mpls_do_cksum(struct mbuf *m)
 u_int8_t
 mpls_getttl(struct mbuf *m, sa_family_t af)
 {
-       struct shim_hdr *shim;
-       struct ip *ip;
-#ifdef INET6
-       struct ip6_hdr *ip6hdr;
-#endif
+       struct mbuf *n;
+       int loc, off;
        u_int8_t ttl = mpls_defttl;
 
        /* If the AF is MPLS then inherit the TTL from the present label. */
-       if (af == AF_MPLS) {
-               shim = mtod(m, struct shim_hdr *);
-               ttl = ntohl(shim->shim_label & MPLS_TTL_MASK);
-               return (ttl);
-       }
-       /* Else extract TTL from the encapsualted packet. */
-       switch (*mtod(m, u_char *) >> 4) {
-       case IPVERSION:
-               if (!mpls_mapttl_ip)
+       if (af == AF_MPLS)
+               loc = 3;
+       else {
+               switch (*mtod(m, uint8_t *) >> 4) {
+               case 4:
+                       if (!mpls_mapttl_ip)
+                               return (ttl);
+
+                       loc = offsetof(struct ip, ip_ttl);
                        break;
-               if (m->m_len < sizeof(*ip))
-                       break;                  /* impossible */
-               ip = mtod(m, struct ip *);
-               ttl = ip->ip_ttl;
-               break;
 #ifdef INET6
-       case IPV6_VERSION >> 4:
-               if (!mpls_mapttl_ip6)
+               case 6:
+                       if (!mpls_mapttl_ip6)
+                               break;
+
+                       loc = offsetof(struct ip6_hdr, ip6_hlim);
                        break;
-               if (m->m_len < sizeof(struct ip6_hdr))
-                       break;                  /* impossible */
-               ip6hdr = mtod(m, struct ip6_hdr *);
-               ttl = ip6hdr->ip6_hlim;
-               break;
 #endif
-       default:
-               break;
+               default:
+                       return (ttl);
+               }
        }
+
+       n = m_getptr(m, loc, &off);
+       if (n == NULL)
+               return (ttl);
+
+       ttl = *(mtod(n, uint8_t *) + off);
+
        return (ttl);
 }
Index: mpls_output.c
===================================================================
RCS file: /cvs/src/sys/netmpls/mpls_output.c,v
retrieving revision 1.26
diff -u -p -r1.26 mpls_output.c
--- mpls_output.c       2 Dec 2015 08:47:00 -0000       1.26
+++ mpls_output.c       26 Aug 2019 09:11:08 -0000
@@ -162,41 +162,39 @@ mpls_do_cksum(struct mbuf *m)
 u_int8_t
 mpls_getttl(struct mbuf *m, sa_family_t af)
 {
-       struct shim_hdr *shim;
-       struct ip *ip;
-#ifdef INET6
-       struct ip6_hdr *ip6hdr;
-#endif
+       struct mbuf *n;
+       int loc, off;
        u_int8_t ttl = mpls_defttl;
 
        /* If the AF is MPLS then inherit the TTL from the present label. */
-       if (af == AF_MPLS) {
-               shim = mtod(m, struct shim_hdr *);
-               ttl = ntohl(shim->shim_label & MPLS_TTL_MASK);
-               return (ttl);
-       }
-       /* Else extract TTL from the encapsualted packet. */
-       switch (*mtod(m, u_char *) >> 4) {
-       case IPVERSION:
-               if (!mpls_mapttl_ip)
+       if (af == AF_MPLS)
+               loc = 3;
+       else {
+               switch (*mtod(m, uint8_t *) >> 4) {
+               case 4:
+                       if (!mpls_mapttl_ip)
+                               return (ttl);
+
+                       loc = offsetof(struct ip, ip_ttl);
                        break;
-               if (m->m_len < sizeof(*ip))
-                       break;                  /* impossible */
-               ip = mtod(m, struct ip *);
-               ttl = ip->ip_ttl;
-               break;
 #ifdef INET6
-       case IPV6_VERSION >> 4:
-               if (!mpls_mapttl_ip6)
+               case 6:
+                       if (!mpls_mapttl_ip6)
+                               break;
+
+                       loc = offsetof(struct ip6_hdr, ip6_hlim);
                        break;
-               if (m->m_len < sizeof(struct ip6_hdr))
-                       break;                  /* impossible */
-               ip6hdr = mtod(m, struct ip6_hdr *);
-               ttl = ip6hdr->ip6_hlim;
-               break;
 #endif
-       default:
-               break;
+               default:
+                       return (ttl);
+               }
        }
+
+       n = m_getptr(m, loc, &off);
+       if (n == NULL)
+               return (ttl);
+
+       ttl = *(mtod(n, uint8_t *) + off);
+
        return (ttl);
 }

Reply via email to