]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zapi_msg.c
zebra: do not load/store wider-than-ptr atomics
[mirror_frr.git] / zebra / zapi_msg.c
index 85eb6b34510214a00ff71607d78649cdaf7ab5a5..a2233a6667a0e8c6fe58482904fe929263956805 100644 (file)
@@ -53,6 +53,7 @@
 #include "zebra/zebra_evpn_mh.h"
 #include "zebra/rt.h"
 #include "zebra/zebra_pbr.h"
+#include "zebra/zebra_tc.h"
 #include "zebra/table_manager.h"
 #include "zebra/zapi_msg.h"
 #include "zebra/zebra_errors.h"
@@ -2606,8 +2607,10 @@ static void zread_sr_policy_set(ZAPI_HANDLER_ARGS)
                return;
 
        policy = zebra_sr_policy_find(zp.color, &zp.endpoint);
-       if (!policy)
+       if (!policy) {
                policy = zebra_sr_policy_add(zp.color, &zp.endpoint, zp.name);
+               policy->sock = client->sock;
+       }
        /* TODO: per-VRF list of SR-TE policies. */
        policy->zvrf = zvrf;
 
@@ -3270,6 +3273,171 @@ stream_failure:
        return;
 }
 
+static inline void zread_tc_qdisc(ZAPI_HANDLER_ARGS)
+{
+       struct zebra_tc_qdisc qdisc;
+       struct stream *s;
+       uint32_t total, i;
+
+       s = msg;
+       STREAM_GETL(s, total);
+
+       for (i = 0; i < total; i++) {
+               memset(&qdisc, 0, sizeof(qdisc));
+
+               qdisc.sock = client->sock;
+               STREAM_GETL(s, qdisc.qdisc.ifindex);
+               STREAM_GETL(s, qdisc.qdisc.kind);
+
+               if (hdr->command == ZEBRA_TC_QDISC_INSTALL)
+                       zebra_tc_qdisc_install(&qdisc);
+               else
+                       zebra_tc_qdisc_uninstall(&qdisc);
+       }
+
+stream_failure:
+       return;
+}
+
+static inline void zread_tc_class(ZAPI_HANDLER_ARGS)
+{
+       struct zebra_tc_class class;
+       struct stream *s;
+       uint32_t total, i;
+
+       s = msg;
+       STREAM_GETL(s, total);
+
+       for (i = 0; i < total; i++) {
+               memset(&class, 0, sizeof(class));
+
+               class.sock = client->sock;
+               STREAM_GETL(s, class.class.ifindex);
+               STREAM_GETL(s, class.class.handle);
+               STREAM_GETL(s, class.class.kind);
+               STREAM_GETQ(s, class.class.u.htb.rate);
+               STREAM_GETQ(s, class.class.u.htb.ceil);
+
+               if (hdr->command == ZEBRA_TC_CLASS_ADD)
+                       zebra_tc_class_add(&class);
+               else
+                       zebra_tc_class_delete(&class);
+       }
+
+stream_failure:
+       return;
+}
+
+static inline void zread_tc_filter(ZAPI_HANDLER_ARGS)
+{
+       struct zebra_tc_filter filter;
+       struct stream *s;
+       uint32_t total, i;
+
+       s = msg;
+       STREAM_GETL(s, total);
+
+       for (i = 0; i < total; i++) {
+               memset(&filter, 0, sizeof(filter));
+
+               filter.sock = client->sock;
+               STREAM_GETL(s, filter.filter.ifindex);
+               STREAM_GETL(s, filter.filter.handle);
+               STREAM_GETL(s, filter.filter.priority);
+               STREAM_GETL(s, filter.filter.protocol);
+               STREAM_GETL(s, filter.filter.kind);
+               switch (filter.filter.kind) {
+               case TC_FILTER_FLOWER: {
+                       STREAM_GETL(s, filter.filter.u.flower.filter_bm);
+                       uint32_t filter_bm = filter.filter.u.flower.filter_bm;
+
+                       if (filter_bm & TC_FLOWER_IP_PROTOCOL)
+                               STREAM_GETC(s, filter.filter.u.flower.ip_proto);
+                       if (filter_bm & TC_FLOWER_SRC_IP) {
+                               STREAM_GETC(
+                                       s,
+                                       filter.filter.u.flower.src_ip.family);
+                               STREAM_GETC(s, filter.filter.u.flower.src_ip
+                                                      .prefixlen);
+                               STREAM_GET(
+                                       &filter.filter.u.flower.src_ip.u.prefix,
+                                       s,
+                                       prefix_blen(&filter.filter.u.flower
+                                                            .src_ip));
+
+                               if (!(filter.filter.u.flower.src_ip.family ==
+                                             AF_INET ||
+                                     filter.filter.u.flower.src_ip.family ==
+                                             AF_INET6)) {
+                                       zlog_warn(
+                                               "Unsupported TC source IP family: %s (%hhu)",
+                                               family2str(
+                                                       filter.filter.u.flower
+                                                               .src_ip.family),
+                                               filter.filter.u.flower.src_ip
+                                                       .family);
+                                       return;
+                               }
+                       }
+                       if (filter_bm & TC_FLOWER_SRC_PORT) {
+                               STREAM_GETW(
+                                       s, filter.filter.u.flower.src_port_min);
+                               STREAM_GETW(
+                                       s, filter.filter.u.flower.src_port_max);
+                       }
+                       if (filter_bm & TC_FLOWER_DST_IP) {
+                               STREAM_GETC(
+                                       s,
+                                       filter.filter.u.flower.dst_ip.family);
+                               STREAM_GETC(s, filter.filter.u.flower.dst_ip
+                                                      .prefixlen);
+                               STREAM_GET(
+                                       &filter.filter.u.flower.dst_ip.u.prefix,
+                                       s,
+                                       prefix_blen(&filter.filter.u.flower
+                                                            .dst_ip));
+                               if (!(filter.filter.u.flower.dst_ip.family ==
+                                             AF_INET ||
+                                     filter.filter.u.flower.dst_ip.family ==
+                                             AF_INET6)) {
+                                       zlog_warn(
+                                               "Unsupported TC destination IP family: %s (%hhu)",
+                                               family2str(
+                                                       filter.filter.u.flower
+                                                               .dst_ip.family),
+                                               filter.filter.u.flower.dst_ip
+                                                       .family);
+                                       return;
+                               }
+                       }
+                       if (filter_bm & TC_FLOWER_DST_PORT) {
+                               STREAM_GETW(
+                                       s, filter.filter.u.flower.dst_port_min);
+                               STREAM_GETW(
+                                       s, filter.filter.u.flower.dst_port_max);
+                       }
+                       if (filter_bm & TC_FLOWER_DSFIELD) {
+                               STREAM_GETC(s, filter.filter.u.flower.dsfield);
+                               STREAM_GETC(
+                                       s, filter.filter.u.flower.dsfield_mask);
+                       }
+                       STREAM_GETL(s, filter.filter.u.flower.classid);
+                       break;
+               }
+               default:
+                       break;
+               }
+
+               if (hdr->command == ZEBRA_TC_FILTER_ADD)
+                       zebra_tc_filter_add(&filter);
+               else
+                       zebra_tc_filter_delete(&filter);
+       }
+
+stream_failure:
+       return;
+}
+
 static inline void zread_ipset(ZAPI_HANDLER_ARGS)
 {
        struct zebra_pbr_ipset zpi;
@@ -3530,7 +3698,7 @@ static inline void zebra_neigh_ip_del(ZAPI_HANDLER_ARGS)
 static inline void zread_iptable(ZAPI_HANDLER_ARGS)
 {
        struct zebra_pbr_iptable *zpi =
-               XCALLOC(MTYPE_TMP, sizeof(struct zebra_pbr_iptable));
+               XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_iptable));
        struct stream *s;
 
        s = msg;
@@ -3770,6 +3938,12 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
        [ZEBRA_CONFIGURE_ARP] = zebra_configure_arp,
        [ZEBRA_GRE_GET] = zebra_gre_get,
        [ZEBRA_GRE_SOURCE_SET] = zebra_gre_source_set,
+       [ZEBRA_TC_QDISC_INSTALL] = zread_tc_qdisc,
+       [ZEBRA_TC_QDISC_UNINSTALL] = zread_tc_qdisc,
+       [ZEBRA_TC_CLASS_ADD] = zread_tc_class,
+       [ZEBRA_TC_CLASS_DELETE] = zread_tc_class,
+       [ZEBRA_TC_FILTER_ADD] = zread_tc_filter,
+       [ZEBRA_TC_FILTER_DELETE] = zread_tc_filter,
 };
 
 /*