diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 060458a534..23d2025156 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -968,6 +968,15 @@ static const NLTypeSystem rtnl_tca_type_system = { .types = rtnl_tca_types, }; +static const NLType mdb_types[] = { + [MDBA_SET_ENTRY] = { .size = sizeof(struct br_port_msg) }, +}; + +static const NLTypeSystem rtnl_mdb_type_system = { + .count = ELEMENTSOF(mdb_types), + .types = mdb_types, +}; + static const NLType error_types[] = { [NLMSGERR_ATTR_MSG] = { .type = NETLINK_TYPE_STRING }, [NLMSGERR_ATTR_OFFS] = { .type = NETLINK_TYPE_U32 }, @@ -1012,6 +1021,9 @@ static const NLType rtnl_types[] = { [RTM_NEWTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, [RTM_DELTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, [RTM_GETTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, + [RTM_NEWMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, + [RTM_DELMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, + [RTM_GETMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, }; const NLTypeSystem rtnl_type_system_root = { diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h index 04e6a98e6b..ddf5686f13 100644 --- a/src/libsystemd/sd-netlink/netlink-util.h +++ b/src/libsystemd/sd-netlink/netlink-util.h @@ -51,6 +51,10 @@ static inline bool rtnl_message_type_is_tclass(uint16_t type) { return IN_SET(type, RTM_NEWTCLASS, RTM_DELTCLASS, RTM_GETTCLASS); } +static inline bool rtnl_message_type_is_mdb(uint16_t type) { + return IN_SET(type, RTM_NEWMDB, RTM_DELMDB, RTM_GETMDB); +} + int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name); int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu); int rtnl_get_link_alternative_names(sd_netlink **rtnl, int ifindex, char ***ret); diff --git a/src/libsystemd/sd-netlink/rtnl-message.c b/src/libsystemd/sd-netlink/rtnl-message.c index 38563e5f34..268150044c 100644 --- a/src/libsystemd/sd-netlink/rtnl-message.c +++ b/src/libsystemd/sd-netlink/rtnl-message.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -1120,3 +1121,24 @@ int sd_rtnl_message_set_tclass_handle(sd_netlink_message *m, uint32_t handle) { return 0; } + +int sd_rtnl_message_new_mdb(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int mdb_ifindex) { + struct br_port_msg *bpm; + int r; + + assert_return(rtnl_message_type_is_mdb(nlmsg_type), -EINVAL); + assert_return(ret, -EINVAL); + + r = message_new(rtnl, ret, nlmsg_type); + if (r < 0) + return r; + + if (nlmsg_type == RTM_NEWMDB) + (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; + + bpm = NLMSG_DATA((*ret)->hdr); + bpm->family = AF_BRIDGE; + bpm->ifindex = mdb_ifindex; + + return 0; +} diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index f9196491d6..ce7ed36d85 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -216,6 +216,8 @@ int sd_rtnl_message_new_tclass(sd_netlink *rtnl, sd_netlink_message **ret, uint1 int sd_rtnl_message_set_tclass_parent(sd_netlink_message *m, uint32_t parent); int sd_rtnl_message_set_tclass_handle(sd_netlink_message *m, uint32_t handle); +int sd_rtnl_message_new_mdb(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int mdb_ifindex); + /* genl */ int sd_genl_socket_open(sd_netlink **nl); int sd_genl_message_new(sd_netlink *nl, sd_genl_family family, uint8_t cmd, sd_netlink_message **m);