]> git.puffer.fish Git - matthieu/frr.git/commitdiff
isisd: Add func to install SRv6 SID in dplane
authorCarmine Scarpitta <carmine.scarpitta@uniroma2.it>
Wed, 22 Feb 2023 10:18:46 +0000 (11:18 +0100)
committerCarmine Scarpitta <carmine.scarpitta@uniroma2.it>
Mon, 11 Sep 2023 15:35:05 +0000 (17:35 +0200)
Add a function to install an SRv6 SID in the data plane through
zebra.

Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
isisd/isis_srv6.h
isisd/isis_zebra.c
isisd/isis_zebra.h

index bae2d0f449f7e90c60ea7897a5407cc32f9a4dcc..094374e89348f55236249797f7b4c1e5512f435a 100644 (file)
@@ -18,6 +18,9 @@
 #define SRV6_MAX_H_ENCAPS 2
 #define SRV6_MAX_END_D 5
 
+/* Name of the interface used for installing SRv6 SIDs into the data plane */
+#define SRV6_IFNAME "sr0"
+
 /* SRv6 SID structure */
 struct isis_srv6_sid_structure {
        uint8_t loc_block_len;
index d05a5bdbb27bc61892ca69d3c536aff0b9d28bca..29fb238af2b751c64e0eaa65a035b167bd4853ff 100644 (file)
@@ -890,6 +890,71 @@ static void isis_zebra_send_localsid(int cmd, const struct in6_addr *sid,
        zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
 }
 
+/**
+ * Install SRv6 SID in the forwarding plane through Zebra.
+ *
+ * @param area         IS-IS area
+ * @param sid          SRv6 SID
+ */
+void isis_zebra_srv6_sid_install(struct isis_area *area,
+                                struct isis_srv6_sid *sid)
+{
+       enum seg6local_action_t action = ZEBRA_SEG6_LOCAL_ACTION_UNSPEC;
+       uint16_t prefixlen = IPV6_MAX_BITLEN;
+       struct seg6local_context ctx = {};
+       struct interface *ifp;
+
+       if (!area || !sid)
+               return;
+
+       sr_debug("ISIS-SRv6 (%s): setting SRv6 SID %pI6", area->area_tag,
+                &sid->sid);
+
+       switch (sid->behavior) {
+       case SRV6_ENDPOINT_BEHAVIOR_END:
+               action = ZEBRA_SEG6_LOCAL_ACTION_END;
+               prefixlen = IPV6_MAX_BITLEN;
+               break;
+       case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID:
+               action = ZEBRA_SEG6_LOCAL_ACTION_END;
+               prefixlen = sid->locator->block_bits_length +
+                           sid->locator->node_bits_length;
+               SET_SRV6_FLV_OP(ctx.flv.flv_ops,
+                               ZEBRA_SEG6_LOCAL_FLV_OP_NEXT_CSID);
+               ctx.flv.lcblock_len = sid->locator->block_bits_length;
+               ctx.flv.lcnode_func_len = sid->locator->node_bits_length;
+               break;
+       case SRV6_ENDPOINT_BEHAVIOR_END_X:
+       case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID:
+       case SRV6_ENDPOINT_BEHAVIOR_RESERVED:
+       case SRV6_ENDPOINT_BEHAVIOR_END_DT6:
+       case SRV6_ENDPOINT_BEHAVIOR_END_DT4:
+       case SRV6_ENDPOINT_BEHAVIOR_END_DT46:
+       case SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID:
+       case SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID:
+       case SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID:
+       case SRV6_ENDPOINT_BEHAVIOR_OPAQUE:
+       default:
+               zlog_err(
+                       "ISIS-SRv6 (%s): unsupported SRv6 endpoint behavior %u",
+                       area->area_tag, sid->behavior);
+               return;
+       }
+
+       /* Attach the SID to the SRv6 interface */
+       ifp = if_lookup_by_name(SRV6_IFNAME, VRF_DEFAULT);
+       if (!ifp) {
+               zlog_warn(
+                       "Failed to install SRv6 SID %pI6: %s interface not found",
+                       &sid->sid, SRV6_IFNAME);
+               return;
+       }
+
+       /* Send the SID to zebra */
+       isis_zebra_send_localsid(ZEBRA_ROUTE_ADD, &sid->sid, prefixlen,
+                                ifp->ifindex, action, &ctx);
+}
+
 /**
  * Callback to process an SRv6 locator chunk received from SRv6 Manager (zebra).
  *
index 94a4666697370e0ba97a07e0261113258b67145b..b4b9d22e81d20de20803dd0b0b8fcebdd7bcb3ba 100644 (file)
@@ -57,6 +57,8 @@ void isis_zebra_vrf_register(struct isis *isis);
 void isis_zebra_vrf_deregister(struct isis *isis);
 int isis_zebra_ls_register(bool up);
 
+extern void isis_zebra_srv6_sid_install(struct isis_area *area,
+                                       struct isis_srv6_sid *sid);
 extern int isis_zebra_srv6_manager_get_locator_chunk(const char *name);
 extern int isis_zebra_srv6_manager_release_locator_chunk(const char *name);