mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-01-04 18:27:53 +00:00
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 <equinox@opensourcerouting.org>
This commit is contained in:
parent
0c58d83688
commit
5c0eed0c85
@ -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 <broadcast|point-to-point>",
|
||||
"ipv6 ospf6 network <broadcast|point-to-point|point-to-multipoint>",
|
||||
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");
|
||||
|
||||
@ -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[];
|
||||
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user