Signed-off-by: Bill Fischofer <bill.fischo...@linaro.org>
---
 platform/linux-generic/odp_packet.c | 41 +++++++++++++++++++++++++++----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/platform/linux-generic/odp_packet.c 
b/platform/linux-generic/odp_packet.c
index db85b5e..a14135f 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -784,6 +784,7 @@ static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr,
        uint8_t ver = ODPH_IPV4HDR_VER(ipv4->ver_ihl);
        uint8_t ihl = ODPH_IPV4HDR_IHL(ipv4->ver_ihl);
        uint16_t frag_offset;
+       uint32_t dstaddr = odp_be_to_cpu_32(ipv4->dst_addr);
 
        pkt_hdr->l3_len = odp_be_to_cpu_16(ipv4->tot_len);
 
@@ -809,6 +810,10 @@ static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr,
        if (odp_unlikely(ODPH_IPV4HDR_IS_FRAGMENT(frag_offset)))
                pkt_hdr->input_flags.ipfrag = 1;
 
+       /* Handle IPv4 broadcast / multicast */
+       pkt_hdr->input_flags.ip_bcast = (dstaddr == 0xffffffff);
+       pkt_hdr->input_flags.ip_mcast = (dstaddr >> 28) == 0xd;
+
        return ipv4->proto;
 }
 
@@ -820,6 +825,7 @@ static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr,
 {
        const odph_ipv6hdr_t *ipv6 = (const odph_ipv6hdr_t *)*parseptr;
        const odph_ipv6hdr_ext_t *ipv6ext;
+       uint32_t dstaddr0 = odp_be_to_cpu_32(ipv6->dst_addr[0]);
 
        pkt_hdr->l3_len = odp_be_to_cpu_16(ipv6->payload_len);
 
@@ -830,11 +836,14 @@ static inline uint8_t parse_ipv6(odp_packet_hdr_t 
*pkt_hdr,
                return 0;
        }
 
+       /* IPv6 broadcast / multicast flags */
+       pkt_hdr->input_flags.ip_mcast = (dstaddr0 & 0xff000000) == 0xff000000;
+       pkt_hdr->input_flags.ip_bcast = 0;
+
        /* Skip past IPv6 header */
        *offset   += sizeof(odph_ipv6hdr_t);
        *parseptr += sizeof(odph_ipv6hdr_t);
 
-
        /* Skip past any IPv6 extension headers */
        if (ipv6->next_hdr == ODPH_IPPROTO_HOPOPTS ||
            ipv6->next_hdr == ODPH_IPPROTO_ROUTE) {
@@ -850,7 +859,8 @@ static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr,
                          ipv6ext->next_hdr == ODPH_IPPROTO_ROUTE) &&
                        *offset < pkt_hdr->frame_len);
 
-               if (*offset >= pkt_hdr->l3_offset + 
odp_be_to_cpu_16(ipv6->payload_len)) {
+               if (*offset >= pkt_hdr->l3_offset +
+                   odp_be_to_cpu_16(ipv6->payload_len)) {
                        pkt_hdr->error_flags.ip_err = 1;
                        return 0;
                }
@@ -938,23 +948,32 @@ int _odp_parse_common(odp_packet_hdr_t *pkt_hdr, const 
uint8_t *ptr)
        uint32_t offset, seglen;
        uint8_t ip_proto = 0;
        const uint8_t *parseptr;
+       uint16_t macaddr0, macaddr2, macaddr4;
 
        offset = sizeof(odph_ethhdr_t);
        if (packet_parse_l2_not_done(pkt_hdr))
                packet_parse_l2(pkt_hdr);
 
-       if (ptr == NULL) {
-               eth = (odph_ethhdr_t *)packet_map(pkt_hdr, 0, &seglen);
-               parseptr = (const uint8_t *)&eth->type;
-               ethtype = odp_be_to_cpu_16(*((const uint16_t *)
-                                          (const void *)parseptr));
+       eth = ptr ? (const odph_ethhdr_t *)ptr :
+               (odph_ethhdr_t *)packet_map(pkt_hdr, 0, &seglen);
+
+       /* Handle Ethernet broadcast/multicast addresses */
+       macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void *)eth));
+       pkt_hdr->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100;
+
+       if (macaddr0 == 0xffff) {
+               macaddr2 = odp_be_to_cpu_16(*((const uint16_t *)eth + 1));
+               macaddr4 = odp_be_to_cpu_16(*((const uint16_t *)eth + 2));
+               pkt_hdr->input_flags.eth_bcast =
+                       (macaddr2 == 0xffff) && (macaddr4 == 0xffff);
        } else {
-               eth = (const odph_ethhdr_t *)ptr;
-               parseptr = (const uint8_t *)&eth->type;
-               ethtype = odp_be_to_cpu_16(*((const uint16_t *)
-                                          (const void *)parseptr));
+               pkt_hdr->input_flags.eth_bcast = 0;
        }
 
+       /* Get Ethertype */
+       parseptr = (const uint8_t *)&eth->type;
+       ethtype = odp_be_to_cpu_16(*((const uint16_t *)
+                                    (const void *)parseptr));
 
        /* Parse the VLAN header(s), if present */
        if (ethtype == ODPH_ETHTYPE_VLAN_OUTER) {
-- 
2.5.0

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to