confd: add support for setting bridge group_fwd_mask

This one was a little bit tricky with the special yang union.  To figure
out the integer value of enums one has to check the schema and deref the
correct subvalue within.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2023-06-20 11:11:52 +02:00
committed by Tobias Waldekranz
parent 587f92cbaa
commit e8c3eff52b
2 changed files with 82 additions and 2 deletions
+44 -2
View File
@@ -652,6 +652,47 @@ static int netdag_gen_vlan(struct dagger *net, struct lyd_node *dif,
return 0;
}
static int netdag_get_bridge_fwd_mask(struct lyd_node *cif)
{
struct lyd_node *node, *proto;
int fwd_mask = 0;
node = lydx_get_descendant(lyd_child(cif), "bridge", NULL);
if (!node)
goto fail;
LYX_LIST_FOR_EACH(lyd_child(node), proto, "ieee-group-forward") {
struct lyd_node_term *leaf = (struct lyd_node_term *)proto;
struct lysc_node_leaf *sleaf = (struct lysc_node_leaf *)leaf->schema;
if ((sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && (sleaf->type->basetype == LY_TYPE_UNION)) {
struct lyd_value *actual = &leaf->value.subvalue->value;
int val;
if (actual->realtype->basetype == LY_TYPE_UINT8)
val = actual->uint8;
else
val = actual->enum_item->value;
fwd_mask |= 1 << val;
}
}
fail:
return fwd_mask;
}
static int netdag_set_bridge(struct dagger *net, struct lyd_node *dif,
struct lyd_node *cif, FILE *ip)
{
const char *ifname = lydx_get_cattr(cif, "name");
fprintf(ip, "link set dev %s type bridge group_fwd_mask %d\n",
ifname, netdag_get_bridge_fwd_mask(cif));
return 0;
}
static int netdag_gen_afspec_add(struct dagger *net, struct lyd_node *dif,
struct lyd_node *cif, FILE *ip)
{
@@ -662,7 +703,8 @@ static int netdag_gen_afspec_add(struct dagger *net, struct lyd_node *dif,
DEBUG_IFACE(dif, "");
if (!strcmp(iftype, "iana-if-type:bridge")) {
fprintf(ip, "link add dev %s type bridge\n", ifname);
fprintf(ip, "link add dev %s type bridge group_fwd_mask %d\n",
ifname, netdag_get_bridge_fwd_mask(cif));
} else if (!strcmp(iftype, "infix-if-type:veth")) {
err = netdag_gen_veth(net, NULL, cif, ip);
} else if (!strcmp(iftype, "iana-if-type:l2vlan")) {
@@ -687,7 +729,7 @@ static int netdag_gen_afspec_set(struct dagger *net, struct lyd_node *dif,
DEBUG_IFACE(dif, "");
if (!strcmp(iftype, "iana-if-type:bridge"))
return 0;
return netdag_set_bridge(net, dif, cif, ip);
if (!strcmp(iftype, "iana-if-type:l2vlan"))
return netdag_gen_vlan(net, dif, cif, ip);
if (!strcmp(iftype, "infix-if-type:veth"))
@@ -31,6 +31,38 @@ submodule infix-if-bridge {
description "Indicates if this bridge supports VLAN filtering.";
}
/*
* Typedefs
*/
typedef ieee-reserved-groups {
type union {
type uint8 {
range "0..15";
}
type enumeration {
enum stp {
value 0;
description "Spanning Tree (STP/RSPT/MSTP).";
}
enum lacp {
value 2;
description "802.3 Slow Protocols, e.g., LACP.";
}
enum dot1x {
value 3;
description "802.1X Port-Based Network Access Control.";
}
enum lldp {
value 14;
description "802.1AB Link Layer Discovery Protocol (LLDP).";
}
}
}
description
"This is a user-friendly enumeration of the different reserved IEEE
reserved link-local multicast groups, in 01:80:C2:00:00:0X.";
}
/*
* Data Nodes
*/
@@ -45,6 +77,12 @@ submodule infix-if-bridge {
container bridge {
description "IEEE 802.1Q style bridge.";
leaf-list ieee-group-forward {
type ieee-reserved-groups;
description
"List of IEEE link-local protocols to forward, e.g., STP, LLDP";
}
container vlans {
if-feature "vlan-filtering";
description "A VLAN filtering bridge has at least one VLAN.";