From: David Lamparter Date: Tue, 27 Jul 2021 08:05:36 +0000 (+0200) Subject: ospf6d: add point-to-multipoint interface mode X-Git-Tag: base_10.0~317^2~7 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=5c0eed0c85e7dba08df24bd7f0ebc17d9a96a030;p=matthieu%2Ffrr.git ospf6d: add point-to-multipoint interface mode This adds the PtMP interface type, which is effectively identical to PtP except that all the database flooding & updates are unicast. Signed-off-by: David Lamparter --- diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index be6d3ac8f9..f86e970b1b 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -49,8 +49,8 @@ DEFINE_HOOK(ospf6_interface_change, unsigned char conf_debug_ospf6_interface = 0; const char *const ospf6_interface_state_str[] = { - "None", "Down", "Loopback", "Waiting", "PointToPoint", - "DROther", "BDR", "DR", NULL}; + "None", "Down", "Loopback", "Waiting", "PointToPoint", + "PtMultipoint", "DROther", "BDR", "DR", NULL}; int ospf6_interface_neighbor_count(struct ospf6_interface *oi) { @@ -451,6 +451,7 @@ void ospf6_interface_connected_route_update(struct interface *ifp) } if (oi->state == OSPF6_INTERFACE_LOOPBACK + || oi->state == OSPF6_INTERFACE_POINTTOMULTIPOINT || oi->state == OSPF6_INTERFACE_POINTTOPOINT) { struct ospf6_route *la_route; @@ -543,7 +544,8 @@ static int ospf6_interface_state_change(uint8_t next_state, OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area); } - if (next_state == OSPF6_INTERFACE_POINTTOPOINT) + if (next_state == OSPF6_INTERFACE_POINTTOPOINT + || next_state == OSPF6_INTERFACE_POINTTOMULTIPOINT) ospf6_if_p2xp_up(oi); hook_call(ospf6_interface_change, oi, next_state, prev_state); @@ -862,6 +864,9 @@ void interface_up(struct event *thread) ospf6_interface_state_change(OSPF6_INTERFACE_LOOPBACK, oi); } else if (oi->type == OSPF_IFTYPE_POINTOPOINT) { ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT, oi); + } else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) { + ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOMULTIPOINT, + oi); } else if (oi->priority == 0) ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi); else { @@ -990,6 +995,8 @@ static const char *ospf6_iftype_str(uint8_t iftype) return "BROADCAST"; case OSPF_IFTYPE_POINTOPOINT: return "POINTOPOINT"; + case OSPF_IFTYPE_POINTOMULTIPOINT: + return "POINTOMULTIPOINT"; } return "UNKNOWN"; } @@ -2573,12 +2580,13 @@ DEFUN (no_ipv6_ospf6_advertise_prefix_list, DEFUN (ipv6_ospf6_network, ipv6_ospf6_network_cmd, - "ipv6 ospf6 network ", + "ipv6 ospf6 network ", IP6_STR OSPF6_STR "Network type\n" "Specify OSPF6 broadcast network\n" "Specify OSPF6 point-to-point network\n" + "Specify OSPF6 point-to-multipoint network\n" ) { VTY_DECLVAR_CONTEXT(interface, ifp); @@ -2604,6 +2612,11 @@ DEFUN (ipv6_ospf6_network, return CMD_SUCCESS; } oi->type = OSPF_IFTYPE_POINTOPOINT; + } else if (strncmp(argv[idx_network]->arg, "point-to-m", 10) == 0) { + if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) { + return CMD_SUCCESS; + } + oi->type = OSPF_IFTYPE_POINTOMULTIPOINT; } /* Reset the interface */ @@ -2763,7 +2776,10 @@ static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf) if (oi->mtu_ignore) vty_out(vty, " ipv6 ospf6 mtu-ignore\n"); - if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT) + if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) + vty_out(vty, + " ipv6 ospf6 network point-to-multipoint\n"); + else if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT) vty_out(vty, " ipv6 ospf6 network point-to-point\n"); else if (oi->type_cfg && oi->type == OSPF_IFTYPE_BROADCAST) vty_out(vty, " ipv6 ospf6 network broadcast\n"); diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h index a627bb3db0..6bd54470eb 100644 --- a/ospf6d/ospf6_interface.h +++ b/ospf6d/ospf6_interface.h @@ -182,15 +182,16 @@ struct ospf6_interface { DECLARE_QOBJ_TYPE(ospf6_interface); /* interface state */ -#define OSPF6_INTERFACE_NONE 0 -#define OSPF6_INTERFACE_DOWN 1 -#define OSPF6_INTERFACE_LOOPBACK 2 -#define OSPF6_INTERFACE_WAITING 3 -#define OSPF6_INTERFACE_POINTTOPOINT 4 -#define OSPF6_INTERFACE_DROTHER 5 -#define OSPF6_INTERFACE_BDR 6 -#define OSPF6_INTERFACE_DR 7 -#define OSPF6_INTERFACE_MAX 8 +#define OSPF6_INTERFACE_NONE 0 +#define OSPF6_INTERFACE_DOWN 1 +#define OSPF6_INTERFACE_LOOPBACK 2 +#define OSPF6_INTERFACE_WAITING 3 +#define OSPF6_INTERFACE_POINTTOPOINT 4 +#define OSPF6_INTERFACE_POINTTOMULTIPOINT 5 +#define OSPF6_INTERFACE_DROTHER 6 +#define OSPF6_INTERFACE_BDR 7 +#define OSPF6_INTERFACE_DR 8 +#define OSPF6_INTERFACE_MAX 9 extern const char *const ospf6_interface_state_str[]; diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index 0b373505a6..cb036752e8 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -321,7 +321,8 @@ void ospf6_router_lsa_originate(struct event *thread) } /* Point-to-Point interfaces */ - if (oi->type == OSPF_IFTYPE_POINTOPOINT) { + if (oi->type == OSPF_IFTYPE_POINTOPOINT + || oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) { for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, j, on)) { if (on->state != OSPF6_NEIGHBOR_FULL) continue; @@ -1068,6 +1069,7 @@ void ospf6_intra_prefix_lsa_originate_stub(struct event *thread) if (oi->state != OSPF6_INTERFACE_LOOPBACK && oi->state != OSPF6_INTERFACE_POINTTOPOINT + && oi->state != OSPF6_INTERFACE_POINTTOMULTIPOINT && full_count != 0) { if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) zlog_debug(" Interface %s is not stub, ignore", diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 244cbe2418..289a1a968c 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -419,7 +419,8 @@ static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst, hello = (struct ospf6_hello *)((caddr_t)oh + sizeof(struct ospf6_header)); - if (oi->state == OSPF6_INTERFACE_POINTTOPOINT + if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT + || oi->state == OSPF6_INTERFACE_POINTTOMULTIPOINT) && oi->p2xp_only_cfg_neigh) { /* NEVER, never, ever, do this on broadcast (or NBMA)! * DR/BDR election requires everyone to talk to everyone else @@ -2326,8 +2327,9 @@ void ospf6_hello_send_addr(struct ospf6_interface *oi, /* Set packet length. */ op->length = length; - if (!addr && oi->state == OSPF6_INTERFACE_POINTTOPOINT - && oi->p2xp_no_multicast_hello) { + if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT + || oi->state == OSPF6_INTERFACE_POINTTOMULTIPOINT) + && !addr && oi->p2xp_no_multicast_hello) { struct listnode *node; struct ospf6_neighbor *on; struct ospf6_packet *opdup; diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index 0ac0765be9..8f7f2bec1a 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -203,7 +203,8 @@ void ospf6_neighbor_lladdr_set(struct ospf6_neighbor *on, memcpy(&on->linklocal_addr, addr, sizeof(struct in6_addr)); - if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT) { + if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT + || on->ospf6_if->type == OSPF_IFTYPE_POINTOMULTIPOINT) { uint32_t prev_cost = ospf6_neighbor_cost(on); p2xp_neigh_refresh(on, prev_cost); @@ -291,6 +292,7 @@ static void ospf6_neighbor_state_change(uint8_t next_state, static int need_adjacency(struct ospf6_neighbor *on) { if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT + || on->ospf6_if->state == OSPF6_INTERFACE_POINTTOMULTIPOINT || on->ospf6_if->state == OSPF6_INTERFACE_DR || on->ospf6_if->state == OSPF6_INTERFACE_BDR) return 1; @@ -799,7 +801,8 @@ static void p2xp_unicast_hello_send(struct event *event); static void p2xp_unicast_hello_sched(struct ospf6_if_p2xp_neighcfg *p2xp_cfg) { if (!p2xp_cfg->poll_interval - || p2xp_cfg->ospf6_if->state != OSPF6_INTERFACE_POINTTOPOINT) + || (p2xp_cfg->ospf6_if->state != OSPF6_INTERFACE_POINTTOMULTIPOINT + && p2xp_cfg->ospf6_if->state != OSPF6_INTERFACE_POINTTOPOINT)) /* state check covers DOWN state too */ EVENT_OFF(p2xp_cfg->t_unicast_hello); else @@ -821,7 +824,8 @@ static void p2xp_unicast_hello_send(struct event *event) struct ospf6_if_p2xp_neighcfg *p2xp_cfg = EVENT_ARG(event); struct ospf6_interface *oi = p2xp_cfg->ospf6_if; - if (oi->state != OSPF6_INTERFACE_POINTTOPOINT) + if (oi->state != OSPF6_INTERFACE_POINTTOPOINT + && oi->state != OSPF6_INTERFACE_POINTTOMULTIPOINT) return; p2xp_unicast_hello_sched(p2xp_cfg); @@ -896,6 +900,8 @@ static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on, /* Neighbor State */ if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT) snprintf(nstate, sizeof(nstate), "PointToPoint"); + else if (on->ospf6_if->type == OSPF_IFTYPE_POINTOMULTIPOINT) + snprintf(nstate, sizeof(nstate), "PtMultipoint"); else { if (on->router_id == on->drouter) snprintf(nstate, sizeof(nstate), "DR"); diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c index f88667bfd0..e42ca3b609 100644 --- a/ospf6d/ospf6_snmp.c +++ b/ospf6d/ospf6_snmp.c @@ -1126,6 +1126,8 @@ static uint8_t *ospfv3IfEntry(struct variable *v, oid *name, size_t *length, return SNMP_INTEGER(1); else if (oi->type == OSPF_IFTYPE_POINTOPOINT) return SNMP_INTEGER(3); + else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) + return SNMP_INTEGER(5); else break; /* Unknown, don't put anything */ case OSPFv3IFADMINSTATUS: @@ -1367,6 +1369,7 @@ static int ospf6TrapIfStateChange(struct ospf6_interface *oi, int next_state, /* Terminal state or regression */ if ((next_state != OSPF6_INTERFACE_POINTTOPOINT) + && (next_state != OSPF6_INTERFACE_POINTTOMULTIPOINT) && (next_state != OSPF6_INTERFACE_DROTHER) && (next_state != OSPF6_INTERFACE_BDR) && (next_state != OSPF6_INTERFACE_DR) && (next_state >= prev_state))