summaryrefslogtreecommitdiffstats
path: root/pimd/pim_bsm.h
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_bsm.h')
-rw-r--r--pimd/pim_bsm.h227
1 files changed, 227 insertions, 0 deletions
diff --git a/pimd/pim_bsm.h b/pimd/pim_bsm.h
new file mode 100644
index 0000000..90bd2f0
--- /dev/null
+++ b/pimd/pim_bsm.h
@@ -0,0 +1,227 @@
+/*
+ * pim_bsm.h: PIM BSM handling related
+ *
+ * Copyright (C) 2018-19 Vmware, Inc.
+ * Saravanan K
+ *
+ * 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
+ */
+
+#ifndef __PIM_BSM_H__
+#define __PIM_BSM_H__
+
+#include "if.h"
+#include "vty.h"
+#include "typesafe.h"
+#include "table.h"
+#include "pim_rp.h"
+#include "pim_msg.h"
+
+/* Defines */
+#define PIM_GBL_SZ_ID 0 /* global scope zone id set to 0 */
+#define PIM_BS_TIME 60 /* RFC 5059 - Sec 5 */
+#define PIM_BSR_DEFAULT_TIMEOUT 130 /* RFC 5059 - Sec 5 */
+
+/* These structures are only encoded IPv4 specific */
+#define PIM_BSM_HDR_LEN sizeof(struct bsm_hdr)
+#define PIM_BSM_GRP_LEN sizeof(struct bsmmsg_grpinfo)
+#define PIM_BSM_RP_LEN sizeof(struct bsmmsg_rpinfo)
+
+#define PIM_MIN_BSM_LEN \
+ (PIM_HDR_LEN + PIM_BSM_HDR_LEN + PIM_BSM_GRP_LEN + PIM_BSM_RP_LEN)
+
+/* Datastructures
+ * ==============
+ */
+
+/* Non candidate BSR states */
+enum ncbsr_state {
+ NO_INFO = 0,
+ ACCEPT_ANY,
+ ACCEPT_PREFERRED
+};
+
+PREDECL_DLIST(bsm_frags);
+
+/* BSM scope - bsm processing is per scope */
+struct bsm_scope {
+ int sz_id; /* scope zone id */
+ enum ncbsr_state state; /* non candidate BSR state */
+ bool accept_nofwd_bsm; /* no fwd bsm accepted for scope */
+ pim_addr current_bsr; /* current elected BSR for the sz */
+ uint32_t current_bsr_prio; /* current BSR priority */
+ int64_t current_bsr_first_ts; /* current BSR elected time */
+ int64_t current_bsr_last_ts; /* Last BSM received from E-BSR */
+ uint16_t bsm_frag_tag; /* Last received frag tag from E-BSR */
+ uint8_t hashMasklen; /* Mask in hash calc RFC 7761 4.7.2 */
+ struct pim_instance *pim; /* Back pointer to pim instance */
+
+ /* current set of fragments for forwarding */
+ struct bsm_frags_head bsm_frags[1];
+
+ struct route_table *bsrp_table; /* group2rp mapping rcvd from BSR */
+ struct thread *bs_timer; /* Boot strap timer */
+};
+
+/* BSM packet (= fragment) - this is stored as list in bsm_frags inside scope
+ * This is used for forwarding to new neighbors or restarting mcast routers
+ */
+struct bsm_frag {
+ struct bsm_frags_item item;
+
+ uint32_t size; /* size of the packet */
+ uint8_t data[0]; /* Actual packet (dyn size) */
+};
+
+DECLARE_DLIST(bsm_frags, struct bsm_frag, item);
+
+PREDECL_SORTLIST_UNIQ(bsm_rpinfos);
+
+/* This is the group node of the bsrp table in scope.
+ * this node maintains the list of rp for the group.
+ */
+struct bsgrp_node {
+ struct prefix group; /* Group range */
+ struct bsm_scope *scope; /* Back ptr to scope */
+
+ /* RPs advertised by BSR, and temporary list while receiving new set */
+ struct bsm_rpinfos_head bsrp_list[1];
+ struct bsm_rpinfos_head partial_bsrp_list[1];
+
+ int pend_rp_cnt; /* Total RP - Received RP */
+ uint16_t frag_tag; /* frag tag to identify the fragment */
+};
+
+/* Items on [partial_]bsrp_list above.
+ * Holds info of each candidate RP received for the bsgrp_node's prefix.
+ */
+struct bsm_rpinfo {
+ struct bsm_rpinfos_item item;
+
+ uint32_t hash; /* Hash Value as per RFC 7761 4.7.2 */
+ uint32_t elapse_time; /* upd at expiry of elected RP node */
+ uint16_t rp_prio; /* RP priority */
+ uint16_t rp_holdtime; /* RP holdtime - g2rp timer value */
+ pim_addr rp_address; /* RP Address */
+ struct bsgrp_node *bsgrp_node; /* Back ptr to bsgrp_node */
+ struct thread *g2rp_timer; /* Run only for elected RP node */
+};
+
+extern int pim_bsm_rpinfo_cmp(const struct bsm_rpinfo *a,
+ const struct bsm_rpinfo *b);
+DECLARE_SORTLIST_UNIQ(bsm_rpinfos, struct bsm_rpinfo, item, pim_bsm_rpinfo_cmp);
+
+/* Structures to extract Bootstrap Message header and Grp to RP Mappings
+ * =====================================================================
+ * BSM Format:
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |PIM Ver| Type |N| Reserved | Checksum | PIM HDR
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Fragment Tag | Hash Mask Len | BSR Priority | BS HDR(1)
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | BSR Address (Encoded-Unicast format) | BS HDR(2)
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Group Address 1 (Encoded-Group format) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RP Count 1 | Frag RP Cnt 1 | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RP Address 1 (Encoded-Unicast format) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RP1 Holdtime | RP1 Priority | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RP Address 2 (Encoded-Unicast format) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RP2 Holdtime | RP2 Priority | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | . |
+ * | . |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RP Address m (Encoded-Unicast format) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RPm Holdtime | RPm Priority | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Group Address 2 (Encoded-Group format) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | . |
+ * | . |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Group Address n (Encoded-Group format) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RP Count n | Frag RP Cnt n | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RP Address 1 (Encoded-Unicast format) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RP1 Holdtime | RP1 Priority | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RP Address 2 (Encoded-Unicast format) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RP2 Holdtime | RP2 Priority | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | . |
+ * | . |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RP Address m (Encoded-Unicast format) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RPm Holdtime | RPm Priority | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct bsm_hdr {
+ uint16_t frag_tag;
+ uint8_t hm_len;
+ uint8_t bsr_prio;
+#if PIM_IPV == 4
+ struct pim_encoded_ipv4_unicast bsr_addr;
+#else
+ struct pim_encoded_ipv6_unicast bsr_addr;
+#endif
+} __attribute__((packed));
+
+struct bsmmsg_grpinfo {
+#if PIM_IPV == 4
+ struct pim_encoded_group_ipv4 group;
+#else
+ struct pim_encoded_group_ipv6 group;
+#endif
+ uint8_t rp_count;
+ uint8_t frag_rp_count;
+ uint16_t reserved;
+} __attribute__((packed));
+
+struct bsmmsg_rpinfo {
+#if PIM_IPV == 4
+ struct pim_encoded_ipv4_unicast rpaddr;
+#else
+ struct pim_encoded_ipv6_unicast rpaddr;
+#endif
+ uint16_t rp_holdtime;
+ uint8_t rp_pri;
+ uint8_t reserved;
+} __attribute__((packed));
+
+/* API */
+void pim_bsm_proc_init(struct pim_instance *pim);
+void pim_bsm_proc_free(struct pim_instance *pim);
+void pim_bsm_clear(struct pim_instance *pim);
+void pim_bsm_write_config(struct vty *vty, struct interface *ifp);
+int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
+ uint32_t buf_size, bool no_fwd);
+bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp);
+struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope,
+ struct prefix *grp);
+#endif