]> git.proxmox.com Git - mirror_frr.git/blobdiff - vrrpd/vrrp_packet.c
Merge pull request #12816 from gpnaveen/stc_rte_err_msg
[mirror_frr.git] / vrrpd / vrrp_packet.c
index 61fcc4e85dad14792a9f07443c0acc783c12a997..36494c7df8b704ed536277ee281f0049aa2d3dcf 100644 (file)
@@ -1,21 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * VRRP packet crafting.
  * Copyright (C) 2018-2019 Cumulus Networks, Inc.
  * Quentin Young
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include <zebra.h>
 #include <netinet/in.h>
@@ -30,7 +17,7 @@
 #include "vrrp_debug.h"
 #include "vrrp_packet.h"
 
-DEFINE_MTYPE_STATIC(VRRPD, VRRP_PKT, "VRRP packet")
+DEFINE_MTYPE_STATIC(VRRPD, VRRP_PKT, "VRRP packet");
 
 /* clang-format off */
 static const char *const vrrp_packet_names[16] = {
@@ -71,7 +58,7 @@ static const char *const vrrp_packet_names[16] = {
  *    VRRP checksum in network byte order.
  */
 static uint16_t vrrp_pkt_checksum(struct vrrp_pkt *pkt, size_t pktsize,
-                                 struct ipaddr *src)
+                                 struct ipaddr *src, bool ipv4_ph)
 {
        uint16_t chksum;
        bool v6 = (src->ipa_type == IPADDR_V6);
@@ -89,13 +76,16 @@ static uint16_t vrrp_pkt_checksum(struct vrrp_pkt *pkt, size_t pktsize,
                ph.next_hdr = IPPROTO_VRRP;
                chksum = in_cksum_with_ph6(&ph, pkt, pktsize);
        } else if (!v6 && ((pkt->hdr.vertype >> 4) == 3)) {
-               struct ipv4_ph ph = {};
-
-               ph.src = src->ipaddr_v4;
-               inet_pton(AF_INET, VRRP_MCASTV4_GROUP_STR, &ph.dst);
-               ph.proto = IPPROTO_VRRP;
-               ph.len = htons(pktsize);
-               chksum = in_cksum_with_ph4(&ph, pkt, pktsize);
+               if (ipv4_ph) {
+                       struct ipv4_ph ph = {};
+
+                       ph.src = src->ipaddr_v4;
+                       inet_pton(AF_INET, VRRP_MCASTV4_GROUP_STR, &ph.dst);
+                       ph.proto = IPPROTO_VRRP;
+                       ph.len = htons(pktsize);
+                       chksum = in_cksum_with_ph4(&ph, pkt, pktsize);
+               } else
+                       chksum = in_cksum(pkt, pktsize);
        } else if (!v6 && ((pkt->hdr.vertype >> 4) == 2)) {
                chksum = in_cksum(pkt, pktsize);
        } else {
@@ -110,7 +100,7 @@ static uint16_t vrrp_pkt_checksum(struct vrrp_pkt *pkt, size_t pktsize,
 ssize_t vrrp_pkt_adver_build(struct vrrp_pkt **pkt, struct ipaddr *src,
                             uint8_t version, uint8_t vrid, uint8_t prio,
                             uint16_t max_adver_int, uint8_t numip,
-                            struct ipaddr **ips)
+                            struct ipaddr **ips, bool ipv4_ph)
 {
        bool v6 = false;
        size_t addrsz = 0;
@@ -147,7 +137,7 @@ ssize_t vrrp_pkt_adver_build(struct vrrp_pkt **pkt, struct ipaddr *src,
                aptr += addrsz;
        }
 
-       (*pkt)->hdr.chksum = vrrp_pkt_checksum(*pkt, pktsize, src);
+       (*pkt)->hdr.chksum = vrrp_pkt_checksum(*pkt, pktsize, src, ipv4_ph);
 
        return pktsize;
 }
@@ -188,10 +178,10 @@ size_t vrrp_pkt_adver_dump(char *buf, size_t buflen, struct vrrp_pkt *pkt)
        return rs;
 }
 
-ssize_t vrrp_pkt_parse_datagram(int family, int version, struct msghdr *m,
-                               size_t read, struct ipaddr *src,
-                               struct vrrp_pkt **pkt, char *errmsg,
-                               size_t errmsg_len)
+ssize_t vrrp_pkt_parse_datagram(int family, int version, bool ipv4_ph,
+                               struct msghdr *m, size_t read,
+                               struct ipaddr *src, struct vrrp_pkt **pkt,
+                               char *errmsg, size_t errmsg_len)
 {
        /* Source (MAC & IP), Dest (MAC & IP) TTL validation done by kernel */
        size_t addrsz = (family == AF_INET) ? sizeof(struct in_addr)
@@ -289,14 +279,14 @@ ssize_t vrrp_pkt_parse_datagram(int family, int version, struct msghdr *m,
        VRRP_PKT_VCHECK(pktver == version, "Bad version %u", pktver);
 
        /* Checksum check */
-       uint16_t chksum = vrrp_pkt_checksum(*pkt, pktsize, src);
+       uint16_t chksum = vrrp_pkt_checksum(*pkt, pktsize, src, ipv4_ph);
 
        VRRP_PKT_VCHECK((*pkt)->hdr.chksum == chksum,
                        "Bad VRRP checksum %hx; should be %hx",
                        (*pkt)->hdr.chksum, chksum);
 
        /* Type check */
-       VRRP_PKT_VCHECK(((*pkt)->hdr.vertype & 0x0F) == 1, "Bad type %hhu",
+       VRRP_PKT_VCHECK(((*pkt)->hdr.vertype & 0x0F) == 1, "Bad type %u",
                        (*pkt)->hdr.vertype & 0x0f);
 
        /* Exact size check */