^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2007-2014 Nicira, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/if_vlan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/jhash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/percpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/tcp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/udp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/div64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/netfilter_bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/netfilter_ipv4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/inetdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/openvswitch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <net/netns/generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "datapath.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "flow.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "flow_table.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include "flow_netlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include "meter.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include "vport-internal_dev.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include "vport-netdev.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned int ovs_net_id __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static struct genl_family dp_packet_genl_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static struct genl_family dp_flow_genl_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static struct genl_family dp_datapath_genl_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static const struct nla_policy flow_policy[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static const struct genl_multicast_group ovs_dp_flow_multicast_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .name = OVS_FLOW_MCGROUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static const struct genl_multicast_group ovs_dp_datapath_multicast_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .name = OVS_DATAPATH_MCGROUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static const struct genl_multicast_group ovs_dp_vport_multicast_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .name = OVS_VPORT_MCGROUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* Check if need to build a reply message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * OVS userspace sets the NLM_F_ECHO flag if it needs the reply. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static bool ovs_must_notify(struct genl_family *family, struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) unsigned int group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return info->nlhdr->nlmsg_flags & NLM_F_ECHO ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) genl_has_listeners(family, genl_info_net(info), group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static void ovs_notify(struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) genl_notify(family, skb, info, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * DOC: Locking:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * All writes e.g. Writes to device state (add/remove datapath, port, set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * operations on vports, etc.), Writes to other state (flow table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * modifications, set miscellaneous datapath parameters, etc.) are protected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * by ovs_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * Reads are protected by RCU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * There are a few special cases (mostly stats) that have their own
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * synchronization but they nest under all of above and don't interact with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * each other.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * The RTNL lock nests inside ovs_mutex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static DEFINE_MUTEX(ovs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) void ovs_lock(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) mutex_lock(&ovs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) void ovs_unlock(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) mutex_unlock(&ovs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #ifdef CONFIG_LOCKDEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int lockdep_ovsl_is_held(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (debug_locks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return lockdep_is_held(&ovs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static struct vport *new_vport(const struct vport_parms *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static int queue_gso_packets(struct datapath *dp, struct sk_buff *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) const struct sw_flow_key *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) const struct dp_upcall_info *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) uint32_t cutlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static int queue_userspace_packet(struct datapath *dp, struct sk_buff *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) const struct sw_flow_key *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) const struct dp_upcall_info *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) uint32_t cutlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void ovs_dp_masks_rebalance(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* Must be called with rcu_read_lock or ovs_mutex. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) const char *ovs_dp_name(const struct datapath *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct vport *vport = ovs_vport_ovsl_rcu(dp, OVSP_LOCAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return ovs_vport_name(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static int get_dpifindex(const struct datapath *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct vport *local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) local = ovs_vport_rcu(dp, OVSP_LOCAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ifindex = local->dev->ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ifindex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static void destroy_dp_rcu(struct rcu_head *rcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct datapath *dp = container_of(rcu, struct datapath, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ovs_flow_tbl_destroy(&dp->table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) free_percpu(dp->stats_percpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) kfree(dp->ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ovs_meters_exit(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) kfree(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static struct hlist_head *vport_hash_bucket(const struct datapath *dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u16 port_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return &dp->ports[port_no & (DP_VPORT_HASH_BUCKETS - 1)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* Called with ovs_mutex or RCU read lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) head = vport_hash_bucket(dp, port_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) hlist_for_each_entry_rcu(vport, head, dp_hash_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) lockdep_ovsl_is_held()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (vport->port_no == port_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* Called with ovs_mutex. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static struct vport *new_vport(const struct vport_parms *parms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) vport = ovs_vport_add(parms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (!IS_ERR(vport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct datapath *dp = parms->dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct hlist_head *head = vport_hash_bucket(dp, vport->port_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) hlist_add_head_rcu(&vport->dp_hash_node, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) void ovs_dp_detach_port(struct vport *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ASSERT_OVSL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* First drop references to device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) hlist_del_rcu(&p->dp_hash_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* Then destroy it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ovs_vport_del(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* Must be called with rcu_read_lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) const struct vport *p = OVS_CB(skb)->input_vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct datapath *dp = p->dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct sw_flow *flow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct sw_flow_actions *sf_acts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct dp_stats_percpu *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) u64 *stats_counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u32 n_mask_hit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) u32 n_cache_hit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) stats = this_cpu_ptr(dp->stats_percpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Look up flow. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) flow = ovs_flow_tbl_lookup_stats(&dp->table, key, skb_get_hash(skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) &n_mask_hit, &n_cache_hit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (unlikely(!flow)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct dp_upcall_info upcall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) memset(&upcall, 0, sizeof(upcall));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) upcall.cmd = OVS_PACKET_CMD_MISS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) upcall.portid = ovs_vport_find_upcall_portid(p, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) upcall.mru = OVS_CB(skb)->mru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) error = ovs_dp_upcall(dp, skb, key, &upcall, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (unlikely(error))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) stats_counter = &stats->n_missed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ovs_flow_stats_update(flow, key->tp.flags, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) sf_acts = rcu_dereference(flow->sf_acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) error = ovs_execute_actions(dp, skb, sf_acts, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (unlikely(error))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) net_dbg_ratelimited("ovs: action execution error on datapath %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ovs_dp_name(dp), error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) stats_counter = &stats->n_hit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* Update datapath statistics. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) u64_stats_update_begin(&stats->syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) (*stats_counter)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) stats->n_mask_hit += n_mask_hit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) stats->n_cache_hit += n_cache_hit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u64_stats_update_end(&stats->syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) const struct sw_flow_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) const struct dp_upcall_info *upcall_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) uint32_t cutlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct dp_stats_percpu *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (upcall_info->portid == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) err = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (!skb_is_gso(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) err = queue_userspace_packet(dp, skb, key, upcall_info, cutlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) err = queue_gso_packets(dp, skb, key, upcall_info, cutlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) stats = this_cpu_ptr(dp->stats_percpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) u64_stats_update_begin(&stats->syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) stats->n_lost++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) u64_stats_update_end(&stats->syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) const struct sw_flow_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) const struct dp_upcall_info *upcall_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) uint32_t cutlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned int gso_type = skb_shinfo(skb)->gso_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct sw_flow_key later_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct sk_buff *segs, *nskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) BUILD_BUG_ON(sizeof(*OVS_CB(skb)) > SKB_GSO_CB_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) segs = __skb_gso_segment(skb, NETIF_F_SG, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (IS_ERR(segs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return PTR_ERR(segs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (segs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (gso_type & SKB_GSO_UDP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* The initial flow key extracted by ovs_flow_key_extract()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * in this case is for a first fragment, so we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * properly mark later fragments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) later_key = *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) later_key.ip.frag = OVS_FRAG_TYPE_LATER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* Queue all of the segments. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) skb_list_walk_safe(segs, skb, nskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (gso_type & SKB_GSO_UDP && skb != segs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) key = &later_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) err = queue_userspace_packet(dp, skb, key, upcall_info, cutlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* Free all of the segments. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) skb_list_walk_safe(segs, skb, nskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) unsigned int hdrlen, int actions_attrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) size_t size = NLMSG_ALIGN(sizeof(struct ovs_header))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) + nla_total_size(hdrlen) /* OVS_PACKET_ATTR_PACKET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) + nla_total_size(ovs_key_attr_size()) /* OVS_PACKET_ATTR_KEY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) + nla_total_size(sizeof(unsigned int)) /* OVS_PACKET_ATTR_LEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) + nla_total_size(sizeof(u64)); /* OVS_PACKET_ATTR_HASH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* OVS_PACKET_ATTR_USERDATA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (upcall_info->userdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) size += NLA_ALIGN(upcall_info->userdata->nla_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* OVS_PACKET_ATTR_EGRESS_TUN_KEY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (upcall_info->egress_tun_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) size += nla_total_size(ovs_tun_key_attr_size());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* OVS_PACKET_ATTR_ACTIONS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (upcall_info->actions_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) size += nla_total_size(actions_attrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /* OVS_PACKET_ATTR_MRU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (upcall_info->mru)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) size += nla_total_size(sizeof(upcall_info->mru));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static void pad_packet(struct datapath *dp, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (!(dp->user_features & OVS_DP_F_UNALIGNED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) size_t plen = NLA_ALIGN(skb->len) - skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (plen > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) skb_put_zero(skb, plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) const struct sw_flow_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) const struct dp_upcall_info *upcall_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) uint32_t cutlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct ovs_header *upcall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct sk_buff *nskb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct sk_buff *user_skb = NULL; /* to be queued to userspace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) unsigned int hlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) int err, dp_ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) u64 hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) dp_ifindex = get_dpifindex(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (!dp_ifindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (skb_vlan_tag_present(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) nskb = skb_clone(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (!nskb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) nskb = __vlan_hwaccel_push_inside(nskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (!nskb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) skb = nskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (nla_attr_size(skb->len) > USHRT_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) err = -EFBIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* Complete checksum if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (skb->ip_summed == CHECKSUM_PARTIAL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) (err = skb_csum_hwoffload_help(skb, 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* Older versions of OVS user space enforce alignment of the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * Netlink attribute to NLA_ALIGNTO which would require extensive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * padding logic. Only perform zerocopy if padding is not required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (dp->user_features & OVS_DP_F_UNALIGNED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) hlen = skb_zerocopy_headlen(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) hlen = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) len = upcall_msg_size(upcall_info, hlen - cutlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) OVS_CB(skb)->acts_origlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) user_skb = genlmsg_new(len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (!user_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) upcall = genlmsg_put(user_skb, 0, 0, &dp_packet_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 0, upcall_info->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (!upcall) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) upcall->dp_ifindex = dp_ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) err = ovs_nla_put_key(key, key, OVS_PACKET_ATTR_KEY, false, user_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (upcall_info->userdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) __nla_put(user_skb, OVS_PACKET_ATTR_USERDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) nla_len(upcall_info->userdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) nla_data(upcall_info->userdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (upcall_info->egress_tun_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) nla = nla_nest_start_noflag(user_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) OVS_PACKET_ATTR_EGRESS_TUN_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (!nla) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) err = ovs_nla_put_tunnel_info(user_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) upcall_info->egress_tun_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) nla_nest_end(user_skb, nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (upcall_info->actions_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) nla = nla_nest_start_noflag(user_skb, OVS_PACKET_ATTR_ACTIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (!nla) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) err = ovs_nla_put_actions(upcall_info->actions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) upcall_info->actions_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) user_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) nla_nest_end(user_skb, nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) nla_nest_cancel(user_skb, nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* Add OVS_PACKET_ATTR_MRU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (upcall_info->mru &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) nla_put_u16(user_skb, OVS_PACKET_ATTR_MRU, upcall_info->mru)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /* Add OVS_PACKET_ATTR_LEN when packet is truncated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (cutlen > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) nla_put_u32(user_skb, OVS_PACKET_ATTR_LEN, skb->len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /* Add OVS_PACKET_ATTR_HASH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) hash = skb_get_hash_raw(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (skb->sw_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) hash |= OVS_PACKET_HASH_SW_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (skb->l4_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) hash |= OVS_PACKET_HASH_L4_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (nla_put(user_skb, OVS_PACKET_ATTR_HASH, sizeof (u64), &hash)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /* Only reserve room for attribute header, packet data is added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * in skb_zerocopy() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (!(nla = nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, 0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) nla->nla_len = nla_attr_size(skb->len - cutlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) err = skb_zerocopy(user_skb, skb, skb->len - cutlen, hlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* Pad OVS_PACKET_ATTR_PACKET if linear copy was performed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) pad_packet(dp, user_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ((struct nlmsghdr *) user_skb->data)->nlmsg_len = user_skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) user_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) skb_tx_error(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) kfree_skb(user_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) kfree_skb(nskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct ovs_header *ovs_header = info->userhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct nlattr **a = info->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct sw_flow_actions *acts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct sk_buff *packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct sw_flow *flow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct sw_flow_actions *sf_acts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) struct vport *input_vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) u16 mru = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) u64 hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) bool log = !a[OVS_PACKET_ATTR_PROBE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (!a[OVS_PACKET_ATTR_PACKET] || !a[OVS_PACKET_ATTR_KEY] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) !a[OVS_PACKET_ATTR_ACTIONS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) len = nla_len(a[OVS_PACKET_ATTR_PACKET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) packet = __dev_alloc_skb(NET_IP_ALIGN + len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (!packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) skb_reserve(packet, NET_IP_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) nla_memcpy(__skb_put(packet, len), a[OVS_PACKET_ATTR_PACKET], len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /* Set packet's mru */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (a[OVS_PACKET_ATTR_MRU]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) mru = nla_get_u16(a[OVS_PACKET_ATTR_MRU]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) packet->ignore_df = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) OVS_CB(packet)->mru = mru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (a[OVS_PACKET_ATTR_HASH]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) hash = nla_get_u64(a[OVS_PACKET_ATTR_HASH]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) __skb_set_hash(packet, hash & 0xFFFFFFFFULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) !!(hash & OVS_PACKET_HASH_SW_BIT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) !!(hash & OVS_PACKET_HASH_L4_BIT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /* Build an sw_flow for sending this packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) flow = ovs_flow_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) err = PTR_ERR(flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (IS_ERR(flow))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) goto err_kfree_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) err = ovs_flow_key_extract_userspace(net, a[OVS_PACKET_ATTR_KEY],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) packet, &flow->key, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) goto err_flow_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) err = ovs_nla_copy_actions(net, a[OVS_PACKET_ATTR_ACTIONS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) &flow->key, &acts, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) goto err_flow_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) rcu_assign_pointer(flow->sf_acts, acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) packet->priority = flow->key.phy.priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) packet->mark = flow->key.phy.skb_mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) dp = get_dp_rcu(net, ovs_header->dp_ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (!dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) input_vport = ovs_vport_rcu(dp, flow->key.phy.in_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (!input_vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) input_vport = ovs_vport_rcu(dp, OVSP_LOCAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (!input_vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) packet->dev = input_vport->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) OVS_CB(packet)->input_vport = input_vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) sf_acts = rcu_dereference(flow->sf_acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) local_bh_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) err = ovs_execute_actions(dp, packet, sf_acts, &flow->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) local_bh_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) ovs_flow_free(flow, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) err_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) err_flow_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) ovs_flow_free(flow, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) err_kfree_skb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) kfree_skb(packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static const struct nla_policy packet_policy[OVS_PACKET_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) [OVS_PACKET_ATTR_PACKET] = { .len = ETH_HLEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) [OVS_PACKET_ATTR_KEY] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) [OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) [OVS_PACKET_ATTR_PROBE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) [OVS_PACKET_ATTR_MRU] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) [OVS_PACKET_ATTR_HASH] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static const struct genl_small_ops dp_packet_genl_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) { .cmd = OVS_PACKET_CMD_EXECUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) .doit = ovs_packet_cmd_execute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static struct genl_family dp_packet_genl_family __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) .hdrsize = sizeof(struct ovs_header),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) .name = OVS_PACKET_FAMILY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) .version = OVS_PACKET_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) .maxattr = OVS_PACKET_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) .policy = packet_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) .netnsok = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) .parallel_ops = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) .small_ops = dp_packet_genl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) .n_small_ops = ARRAY_SIZE(dp_packet_genl_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) static void get_dp_stats(const struct datapath *dp, struct ovs_dp_stats *stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct ovs_dp_megaflow_stats *mega_stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) memset(mega_stats, 0, sizeof(*mega_stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) stats->n_flows = ovs_flow_tbl_count(&dp->table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) mega_stats->n_masks = ovs_flow_tbl_num_masks(&dp->table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) stats->n_hit = stats->n_missed = stats->n_lost = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) for_each_possible_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) const struct dp_stats_percpu *percpu_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct dp_stats_percpu local_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) unsigned int start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) percpu_stats = per_cpu_ptr(dp->stats_percpu, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) start = u64_stats_fetch_begin_irq(&percpu_stats->syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) local_stats = *percpu_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) } while (u64_stats_fetch_retry_irq(&percpu_stats->syncp, start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) stats->n_hit += local_stats.n_hit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) stats->n_missed += local_stats.n_missed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) stats->n_lost += local_stats.n_lost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) mega_stats->n_mask_hit += local_stats.n_mask_hit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) mega_stats->n_cache_hit += local_stats.n_cache_hit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static bool should_fill_key(const struct sw_flow_id *sfid, uint32_t ufid_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return ovs_identifier_is_ufid(sfid) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) !(ufid_flags & OVS_UFID_F_OMIT_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static bool should_fill_mask(uint32_t ufid_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return !(ufid_flags & OVS_UFID_F_OMIT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) static bool should_fill_actions(uint32_t ufid_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return !(ufid_flags & OVS_UFID_F_OMIT_ACTIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static size_t ovs_flow_cmd_msg_size(const struct sw_flow_actions *acts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) const struct sw_flow_id *sfid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) uint32_t ufid_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) size_t len = NLMSG_ALIGN(sizeof(struct ovs_header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) /* OVS_FLOW_ATTR_UFID, or unmasked flow key as fallback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * see ovs_nla_put_identifier()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (sfid && ovs_identifier_is_ufid(sfid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) len += nla_total_size(sfid->ufid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) len += nla_total_size(ovs_key_attr_size());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) /* OVS_FLOW_ATTR_KEY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (!sfid || should_fill_key(sfid, ufid_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) len += nla_total_size(ovs_key_attr_size());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /* OVS_FLOW_ATTR_MASK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (should_fill_mask(ufid_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) len += nla_total_size(ovs_key_attr_size());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /* OVS_FLOW_ATTR_ACTIONS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (should_fill_actions(ufid_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) len += nla_total_size(acts->orig_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) + nla_total_size_64bit(sizeof(struct ovs_flow_stats)) /* OVS_FLOW_ATTR_STATS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) + nla_total_size(1) /* OVS_FLOW_ATTR_TCP_FLAGS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) + nla_total_size_64bit(8); /* OVS_FLOW_ATTR_USED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) /* Called with ovs_mutex or RCU read lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) static int ovs_flow_cmd_fill_stats(const struct sw_flow *flow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct ovs_flow_stats stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) __be16 tcp_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) unsigned long used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) ovs_flow_stats_get(flow, &stats, &used, &tcp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (used &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) nla_put_u64_64bit(skb, OVS_FLOW_ATTR_USED, ovs_flow_used_time(used),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) OVS_FLOW_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (stats.n_packets &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) nla_put_64bit(skb, OVS_FLOW_ATTR_STATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) sizeof(struct ovs_flow_stats), &stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) OVS_FLOW_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if ((u8)ntohs(tcp_flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) nla_put_u8(skb, OVS_FLOW_ATTR_TCP_FLAGS, (u8)ntohs(tcp_flags)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /* Called with ovs_mutex or RCU read lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static int ovs_flow_cmd_fill_actions(const struct sw_flow *flow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) struct sk_buff *skb, int skb_orig_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) struct nlattr *start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) /* If OVS_FLOW_ATTR_ACTIONS doesn't fit, skip dumping the actions if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * this is the first flow to be dumped into 'skb'. This is unusual for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) * Netlink but individual action lists can be longer than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * NLMSG_GOODSIZE and thus entirely undumpable if we didn't do this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * The userspace caller can always fetch the actions separately if it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * really wants them. (Most userspace callers in fact don't care.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * This can only fail for dump operations because the skb is always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * properly sized for single flows.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) start = nla_nest_start_noflag(skb, OVS_FLOW_ATTR_ACTIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) const struct sw_flow_actions *sf_acts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) sf_acts = rcu_dereference_ovsl(flow->sf_acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) err = ovs_nla_put_actions(sf_acts->actions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) sf_acts->actions_len, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) nla_nest_end(skb, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (skb_orig_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) nla_nest_cancel(skb, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) } else if (skb_orig_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* Called with ovs_mutex or RCU read lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) static int ovs_flow_cmd_fill_info(const struct sw_flow *flow, int dp_ifindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) struct sk_buff *skb, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) u32 seq, u32 flags, u8 cmd, u32 ufid_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) const int skb_orig_len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct ovs_header *ovs_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) ovs_header = genlmsg_put(skb, portid, seq, &dp_flow_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (!ovs_header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) ovs_header->dp_ifindex = dp_ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) err = ovs_nla_put_identifier(flow, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (should_fill_key(&flow->id, ufid_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) err = ovs_nla_put_masked_key(flow, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (should_fill_mask(ufid_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) err = ovs_nla_put_mask(flow, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) err = ovs_flow_cmd_fill_stats(flow, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (should_fill_actions(ufid_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) err = ovs_flow_cmd_fill_actions(flow, skb, skb_orig_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) genlmsg_end(skb, ovs_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) genlmsg_cancel(skb, ovs_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) /* May not be called with RCU read lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static struct sk_buff *ovs_flow_cmd_alloc_info(const struct sw_flow_actions *acts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) const struct sw_flow_id *sfid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) bool always,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) uint32_t ufid_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (!always && !ovs_must_notify(&dp_flow_genl_family, info, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) len = ovs_flow_cmd_msg_size(acts, sfid, ufid_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) skb = genlmsg_new(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) /* Called with ovs_mutex. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static struct sk_buff *ovs_flow_cmd_build_info(const struct sw_flow *flow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) int dp_ifindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct genl_info *info, u8 cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) bool always, u32 ufid_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) skb = ovs_flow_cmd_alloc_info(ovsl_dereference(flow->sf_acts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) &flow->id, info, always, ufid_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (IS_ERR_OR_NULL(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) retval = ovs_flow_cmd_fill_info(flow, dp_ifindex, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) cmd, ufid_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (WARN_ON_ONCE(retval < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) skb = ERR_PTR(retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct nlattr **a = info->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct ovs_header *ovs_header = info->userhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct sw_flow *flow = NULL, *new_flow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) struct sw_flow_mask mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) struct sk_buff *reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct sw_flow_actions *acts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct sw_flow_match match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) bool log = !a[OVS_FLOW_ATTR_PROBE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) /* Must have key and actions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (!a[OVS_FLOW_ATTR_KEY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) OVS_NLERR(log, "Flow key attr not present in new flow.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (!a[OVS_FLOW_ATTR_ACTIONS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) OVS_NLERR(log, "Flow actions attr not present in new flow.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) /* Most of the time we need to allocate a new flow, do it before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) * locking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) new_flow = ovs_flow_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (IS_ERR(new_flow)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) error = PTR_ERR(new_flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) /* Extract key. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) ovs_match_init(&match, &new_flow->key, false, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) a[OVS_FLOW_ATTR_MASK], log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) goto err_kfree_flow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /* Extract flow identifier. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) error = ovs_nla_get_identifier(&new_flow->id, a[OVS_FLOW_ATTR_UFID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) &new_flow->key, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) goto err_kfree_flow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) /* unmasked key is needed to match when ufid is not used. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (ovs_identifier_is_key(&new_flow->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) match.key = new_flow->id.unmasked_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) ovs_flow_mask_key(&new_flow->key, &new_flow->key, true, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) /* Validate actions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) error = ovs_nla_copy_actions(net, a[OVS_FLOW_ATTR_ACTIONS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) &new_flow->key, &acts, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) OVS_NLERR(log, "Flow actions may not be safe on all matching packets.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) goto err_kfree_flow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) reply = ovs_flow_cmd_alloc_info(acts, &new_flow->id, info, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) ufid_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (IS_ERR(reply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) error = PTR_ERR(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) goto err_kfree_acts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) dp = get_dp(net, ovs_header->dp_ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (unlikely(!dp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) goto err_unlock_ovs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /* Check if this is a duplicate flow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (ovs_identifier_is_ufid(&new_flow->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) flow = ovs_flow_tbl_lookup_ufid(&dp->table, &new_flow->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (!flow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) flow = ovs_flow_tbl_lookup(&dp->table, &new_flow->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (likely(!flow)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) rcu_assign_pointer(new_flow->sf_acts, acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) /* Put flow in bucket. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) error = ovs_flow_tbl_insert(&dp->table, new_flow, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (unlikely(error)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) acts = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) goto err_unlock_ovs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (unlikely(reply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) error = ovs_flow_cmd_fill_info(new_flow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) ovs_header->dp_ifindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) reply, info->snd_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) OVS_FLOW_CMD_NEW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) ufid_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) BUG_ON(error < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) struct sw_flow_actions *old_acts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) /* Bail out if we're not allowed to modify an existing flow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) * We accept NLM_F_CREATE in place of the intended NLM_F_EXCL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * because Generic Netlink treats the latter as a dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) * request. We also accept NLM_F_EXCL in case that bug ever
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * gets fixed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (unlikely(info->nlhdr->nlmsg_flags & (NLM_F_CREATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) | NLM_F_EXCL))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) error = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) goto err_unlock_ovs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /* The flow identifier has to be the same for flow updates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) * Look for any overlapping flow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (unlikely(!ovs_flow_cmp(flow, &match))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (ovs_identifier_is_key(&flow->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) flow = ovs_flow_tbl_lookup_exact(&dp->table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) &match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) else /* UFID matches but key is different */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) flow = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (!flow) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) error = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) goto err_unlock_ovs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) /* Update actions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) old_acts = ovsl_dereference(flow->sf_acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) rcu_assign_pointer(flow->sf_acts, acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (unlikely(reply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) error = ovs_flow_cmd_fill_info(flow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) ovs_header->dp_ifindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) reply, info->snd_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) OVS_FLOW_CMD_NEW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) ufid_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) BUG_ON(error < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) ovs_nla_free_flow_actions_rcu(old_acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) ovs_flow_free(new_flow, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) ovs_notify(&dp_flow_genl_family, reply, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) err_unlock_ovs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) kfree_skb(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) err_kfree_acts:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) ovs_nla_free_flow_actions(acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) err_kfree_flow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) ovs_flow_free(new_flow, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) /* Factor out action copy to avoid "Wframe-larger-than=1024" warning. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) static noinline_for_stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) struct sw_flow_actions *get_flow_actions(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) const struct nlattr *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) const struct sw_flow_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) const struct sw_flow_mask *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct sw_flow_actions *acts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) struct sw_flow_key masked_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) ovs_flow_mask_key(&masked_key, key, true, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) error = ovs_nla_copy_actions(net, a, &masked_key, &acts, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) OVS_NLERR(log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) "Actions may not be safe on all matching packets");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) return acts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) /* Factor out match-init and action-copy to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * "Wframe-larger-than=1024" warning. Because mask is only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) * used to get actions, we new a function to save some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) * stack space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) * If there are not key and action attrs, we return 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) * directly. In the case, the caller will also not use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) * match as before. If there is action attr, we try to get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) * actions and save them to *acts. Before returning from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) * the function, we reset the match->mask pointer. Because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) * we should not to return match object with dangling reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) * to mask.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) * */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) static noinline_for_stack int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) ovs_nla_init_match_and_action(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) struct sw_flow_match *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) struct sw_flow_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) struct nlattr **a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) struct sw_flow_actions **acts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) struct sw_flow_mask mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (a[OVS_FLOW_ATTR_KEY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) ovs_match_init(match, key, true, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) error = ovs_nla_get_match(net, match, a[OVS_FLOW_ATTR_KEY],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) a[OVS_FLOW_ATTR_MASK], log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) if (a[OVS_FLOW_ATTR_ACTIONS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (!a[OVS_FLOW_ATTR_KEY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) OVS_NLERR(log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) "Flow key attribute not present in set flow.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) *acts = get_flow_actions(net, a[OVS_FLOW_ATTR_ACTIONS], key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) &mask, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (IS_ERR(*acts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) error = PTR_ERR(*acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) /* On success, error is 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) match->mask = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) struct nlattr **a = info->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct ovs_header *ovs_header = info->userhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) struct sw_flow_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) struct sw_flow *flow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) struct sk_buff *reply = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) struct sw_flow_actions *old_acts = NULL, *acts = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) struct sw_flow_match match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) struct sw_flow_id sfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) bool log = !a[OVS_FLOW_ATTR_PROBE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) bool ufid_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) ufid_present = ovs_nla_get_ufid(&sfid, a[OVS_FLOW_ATTR_UFID], log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (!a[OVS_FLOW_ATTR_KEY] && !ufid_present) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) OVS_NLERR(log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) "Flow set message rejected, Key attribute missing.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) error = ovs_nla_init_match_and_action(net, &match, &key, a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) &acts, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (acts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /* Can allocate before locking if have acts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) reply = ovs_flow_cmd_alloc_info(acts, &sfid, info, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) ufid_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (IS_ERR(reply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) error = PTR_ERR(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) goto err_kfree_acts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) dp = get_dp(net, ovs_header->dp_ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (unlikely(!dp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) goto err_unlock_ovs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) /* Check that the flow exists. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (ufid_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) flow = ovs_flow_tbl_lookup_ufid(&dp->table, &sfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (unlikely(!flow)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) error = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) goto err_unlock_ovs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) /* Update actions, if present. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) if (likely(acts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) old_acts = ovsl_dereference(flow->sf_acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) rcu_assign_pointer(flow->sf_acts, acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (unlikely(reply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) error = ovs_flow_cmd_fill_info(flow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) ovs_header->dp_ifindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) reply, info->snd_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) OVS_FLOW_CMD_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) ufid_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) BUG_ON(error < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) /* Could not alloc without acts before locking. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) reply = ovs_flow_cmd_build_info(flow, ovs_header->dp_ifindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) info, OVS_FLOW_CMD_SET, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) ufid_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (IS_ERR(reply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) error = PTR_ERR(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) goto err_unlock_ovs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) /* Clear stats. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) if (a[OVS_FLOW_ATTR_CLEAR])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) ovs_flow_stats_clear(flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) ovs_notify(&dp_flow_genl_family, reply, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (old_acts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) ovs_nla_free_flow_actions_rcu(old_acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) err_unlock_ovs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) kfree_skb(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) err_kfree_acts:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) ovs_nla_free_flow_actions(acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) struct nlattr **a = info->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) struct ovs_header *ovs_header = info->userhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) struct sw_flow_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) struct sk_buff *reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) struct sw_flow *flow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) struct sw_flow_match match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) struct sw_flow_id ufid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) bool log = !a[OVS_FLOW_ATTR_PROBE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) bool ufid_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) ufid_present = ovs_nla_get_ufid(&ufid, a[OVS_FLOW_ATTR_UFID], log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (a[OVS_FLOW_ATTR_KEY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) ovs_match_init(&match, &key, true, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) err = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY], NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) } else if (!ufid_present) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) OVS_NLERR(log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) "Flow get message rejected, Key attribute missing.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (!dp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (ufid_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) flow = ovs_flow_tbl_lookup_ufid(&dp->table, &ufid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (!flow) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) reply = ovs_flow_cmd_build_info(flow, ovs_header->dp_ifindex, info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) OVS_FLOW_CMD_GET, true, ufid_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (IS_ERR(reply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) err = PTR_ERR(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return genlmsg_reply(reply, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) struct nlattr **a = info->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) struct ovs_header *ovs_header = info->userhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) struct sw_flow_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) struct sk_buff *reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) struct sw_flow *flow = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) struct sw_flow_match match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct sw_flow_id ufid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) bool log = !a[OVS_FLOW_ATTR_PROBE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) bool ufid_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) ufid_present = ovs_nla_get_ufid(&ufid, a[OVS_FLOW_ATTR_UFID], log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) if (a[OVS_FLOW_ATTR_KEY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) ovs_match_init(&match, &key, true, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) err = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) NULL, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (unlikely(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (unlikely(!dp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) if (unlikely(!a[OVS_FLOW_ATTR_KEY] && !ufid_present)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) err = ovs_flow_tbl_flush(&dp->table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (ufid_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) flow = ovs_flow_tbl_lookup_ufid(&dp->table, &ufid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (unlikely(!flow)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) ovs_flow_tbl_remove(&dp->table, flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) reply = ovs_flow_cmd_alloc_info((const struct sw_flow_actions __force *) flow->sf_acts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) &flow->id, info, false, ufid_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (likely(reply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (!IS_ERR(reply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) rcu_read_lock(); /*To keep RCU checker happy. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) err = ovs_flow_cmd_fill_info(flow, ovs_header->dp_ifindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) reply, info->snd_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) OVS_FLOW_CMD_DEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) ufid_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (WARN_ON_ONCE(err < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) kfree_skb(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) ovs_notify(&dp_flow_genl_family, reply, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) netlink_set_err(sock_net(skb->sk)->genl_sock, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) PTR_ERR(reply));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) ovs_flow_free(flow, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) struct nlattr *a[__OVS_FLOW_ATTR_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) struct ovs_header *ovs_header = genlmsg_data(nlmsg_data(cb->nlh));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) struct table_instance *ti;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) u32 ufid_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) err = genlmsg_parse_deprecated(cb->nlh, &dp_flow_genl_family, a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) OVS_FLOW_ATTR_MAX, flow_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) dp = get_dp_rcu(sock_net(skb->sk), ovs_header->dp_ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) if (!dp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) ti = rcu_dereference(dp->table.ti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) struct sw_flow *flow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) u32 bucket, obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) bucket = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) obj = cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) flow = ovs_flow_tbl_dump_next(ti, &bucket, &obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (!flow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) if (ovs_flow_cmd_fill_info(flow, ovs_header->dp_ifindex, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) OVS_FLOW_CMD_GET, ufid_flags) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) cb->args[0] = bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) cb->args[1] = obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) static const struct nla_policy flow_policy[OVS_FLOW_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) [OVS_FLOW_ATTR_KEY] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) [OVS_FLOW_ATTR_MASK] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) [OVS_FLOW_ATTR_ACTIONS] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) [OVS_FLOW_ATTR_CLEAR] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) [OVS_FLOW_ATTR_PROBE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) [OVS_FLOW_ATTR_UFID] = { .type = NLA_UNSPEC, .len = 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) [OVS_FLOW_ATTR_UFID_FLAGS] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) static const struct genl_small_ops dp_flow_genl_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) { .cmd = OVS_FLOW_CMD_NEW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) .doit = ovs_flow_cmd_new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) { .cmd = OVS_FLOW_CMD_DEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) .doit = ovs_flow_cmd_del
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) { .cmd = OVS_FLOW_CMD_GET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) .flags = 0, /* OK for unprivileged users. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) .doit = ovs_flow_cmd_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) .dumpit = ovs_flow_cmd_dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) { .cmd = OVS_FLOW_CMD_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) .doit = ovs_flow_cmd_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) static struct genl_family dp_flow_genl_family __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) .hdrsize = sizeof(struct ovs_header),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) .name = OVS_FLOW_FAMILY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) .version = OVS_FLOW_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) .maxattr = OVS_FLOW_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) .policy = flow_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) .netnsok = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) .parallel_ops = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) .small_ops = dp_flow_genl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) .n_small_ops = ARRAY_SIZE(dp_flow_genl_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) .mcgrps = &ovs_dp_flow_multicast_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) .n_mcgrps = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) static size_t ovs_dp_cmd_msg_size(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) size_t msgsize = NLMSG_ALIGN(sizeof(struct ovs_header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) msgsize += nla_total_size(IFNAMSIZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) msgsize += nla_total_size_64bit(sizeof(struct ovs_dp_stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) msgsize += nla_total_size_64bit(sizeof(struct ovs_dp_megaflow_stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) msgsize += nla_total_size(sizeof(u32)); /* OVS_DP_ATTR_USER_FEATURES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) msgsize += nla_total_size(sizeof(u32)); /* OVS_DP_ATTR_MASKS_CACHE_SIZE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) return msgsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) /* Called with ovs_mutex. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) u32 portid, u32 seq, u32 flags, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) struct ovs_header *ovs_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) struct ovs_dp_stats dp_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) struct ovs_dp_megaflow_stats dp_megaflow_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) ovs_header = genlmsg_put(skb, portid, seq, &dp_datapath_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if (!ovs_header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) ovs_header->dp_ifindex = get_dpifindex(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) err = nla_put_string(skb, OVS_DP_ATTR_NAME, ovs_dp_name(dp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) get_dp_stats(dp, &dp_stats, &dp_megaflow_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) if (nla_put_64bit(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) &dp_stats, OVS_DP_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) if (nla_put_64bit(skb, OVS_DP_ATTR_MEGAFLOW_STATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) sizeof(struct ovs_dp_megaflow_stats),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) &dp_megaflow_stats, OVS_DP_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) if (nla_put_u32(skb, OVS_DP_ATTR_USER_FEATURES, dp->user_features))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (nla_put_u32(skb, OVS_DP_ATTR_MASKS_CACHE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) ovs_flow_tbl_masks_cache_size(&dp->table)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) genlmsg_end(skb, ovs_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) genlmsg_cancel(skb, ovs_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) static struct sk_buff *ovs_dp_cmd_alloc_info(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) return genlmsg_new(ovs_dp_cmd_msg_size(), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) /* Called with rcu_read_lock or ovs_mutex. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) static struct datapath *lookup_datapath(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) const struct ovs_header *ovs_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) struct nlattr *a[OVS_DP_ATTR_MAX + 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (!a[OVS_DP_ATTR_NAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) dp = get_dp(net, ovs_header->dp_ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) vport = ovs_vport_locate(net, nla_data(a[OVS_DP_ATTR_NAME]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) dp = vport && vport->port_no == OVSP_LOCAL ? vport->dp : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) return dp ? dp : ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) static void ovs_dp_reset_user_features(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) dp = lookup_datapath(sock_net(skb->sk), info->userhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) if (IS_ERR(dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) WARN(dp->user_features, "Dropping previously announced user features\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) dp->user_features = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) DEFINE_STATIC_KEY_FALSE(tc_recirc_sharing_support);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) static int ovs_dp_change(struct datapath *dp, struct nlattr *a[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) u32 user_features = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) if (a[OVS_DP_ATTR_USER_FEATURES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) user_features = nla_get_u32(a[OVS_DP_ATTR_USER_FEATURES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) if (user_features & ~(OVS_DP_F_VPORT_PIDS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) OVS_DP_F_UNALIGNED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) OVS_DP_F_TC_RECIRC_SHARING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) #if !IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) if (user_features & OVS_DP_F_TC_RECIRC_SHARING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) if (a[OVS_DP_ATTR_MASKS_CACHE_SIZE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) u32 cache_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) cache_size = nla_get_u32(a[OVS_DP_ATTR_MASKS_CACHE_SIZE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) err = ovs_flow_tbl_masks_cache_resize(&dp->table, cache_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) dp->user_features = user_features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (dp->user_features & OVS_DP_F_TC_RECIRC_SHARING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) static_branch_enable(&tc_recirc_sharing_support);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) static_branch_disable(&tc_recirc_sharing_support);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) static int ovs_dp_stats_init(struct datapath *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) dp->stats_percpu = netdev_alloc_pcpu_stats(struct dp_stats_percpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) if (!dp->stats_percpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) static int ovs_dp_vport_init(struct datapath *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) dp->ports = kmalloc_array(DP_VPORT_HASH_BUCKETS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) sizeof(struct hlist_head),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) if (!dp->ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) INIT_HLIST_HEAD(&dp->ports[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) struct nlattr **a = info->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) struct vport_parms parms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) struct sk_buff *reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) struct ovs_net *ovs_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) if (!a[OVS_DP_ATTR_NAME] || !a[OVS_DP_ATTR_UPCALL_PID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) reply = ovs_dp_cmd_alloc_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if (!reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) dp = kzalloc(sizeof(*dp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if (dp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) goto err_destroy_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) ovs_dp_set_net(dp, sock_net(skb->sk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) /* Allocate table. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) err = ovs_flow_tbl_init(&dp->table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) goto err_destroy_dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) err = ovs_dp_stats_init(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) goto err_destroy_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) err = ovs_dp_vport_init(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) goto err_destroy_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) err = ovs_meters_init(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) goto err_destroy_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) /* Set up our datapath device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) parms.name = nla_data(a[OVS_DP_ATTR_NAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) parms.type = OVS_VPORT_TYPE_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) parms.options = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) parms.dp = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) parms.port_no = OVSP_LOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) parms.upcall_portids = a[OVS_DP_ATTR_UPCALL_PID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) /* So far only local changes have been made, now need the lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) err = ovs_dp_change(dp, a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) goto err_unlock_and_destroy_meters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) vport = new_vport(&parms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) if (IS_ERR(vport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) err = PTR_ERR(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) if (err == -EBUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) err = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) if (err == -EEXIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) /* An outdated user space instance that does not understand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) * the concept of user_features has attempted to create a new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) * datapath and is likely to reuse it. Drop all user features.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) if (info->genlhdr->version < OVS_DP_VER_FEATURES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) ovs_dp_reset_user_features(skb, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) goto err_unlock_and_destroy_meters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) info->snd_seq, 0, OVS_DP_CMD_NEW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) BUG_ON(err < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) ovs_net = net_generic(ovs_dp_get_net(dp), ovs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) list_add_tail_rcu(&dp->list_node, &ovs_net->dps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) ovs_notify(&dp_datapath_genl_family, reply, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) err_unlock_and_destroy_meters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) ovs_meters_exit(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) err_destroy_ports:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) kfree(dp->ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) err_destroy_stats:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) free_percpu(dp->stats_percpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) err_destroy_table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) ovs_flow_tbl_destroy(&dp->table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) err_destroy_dp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) kfree(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) err_destroy_reply:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) kfree_skb(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) /* Called with ovs_mutex. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) static void __dp_destroy(struct datapath *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) struct flow_table *table = &dp->table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) struct hlist_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) if (vport->port_no != OVSP_LOCAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) ovs_dp_detach_port(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) list_del_rcu(&dp->list_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) /* OVSP_LOCAL is datapath internal port. We need to make sure that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) * all ports in datapath are destroyed first before freeing datapath.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) ovs_dp_detach_port(ovs_vport_ovsl(dp, OVSP_LOCAL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) /* Flush sw_flow in the tables. RCU cb only releases resource
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) * such as dp, ports and tables. That may avoid some issues
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) * such as RCU usage warning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) table_instance_flow_flush(table, ovsl_dereference(table->ti),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) ovsl_dereference(table->ufid_ti));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) /* RCU destroy the ports, meters and flow tables. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) call_rcu(&dp->rcu, destroy_dp_rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) struct sk_buff *reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) reply = ovs_dp_cmd_alloc_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) if (!reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) err = PTR_ERR(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (IS_ERR(dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) goto err_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) info->snd_seq, 0, OVS_DP_CMD_DEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) BUG_ON(err < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) __dp_destroy(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) ovs_notify(&dp_datapath_genl_family, reply, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) err_unlock_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) kfree_skb(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) struct sk_buff *reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) reply = ovs_dp_cmd_alloc_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) if (!reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) err = PTR_ERR(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) if (IS_ERR(dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) goto err_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) err = ovs_dp_change(dp, info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) goto err_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) info->snd_seq, 0, OVS_DP_CMD_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) BUG_ON(err < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) ovs_notify(&dp_datapath_genl_family, reply, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) err_unlock_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) kfree_skb(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) struct sk_buff *reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) reply = ovs_dp_cmd_alloc_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if (!reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) if (IS_ERR(dp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) err = PTR_ERR(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) goto err_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) info->snd_seq, 0, OVS_DP_CMD_GET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) BUG_ON(err < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) return genlmsg_reply(reply, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) err_unlock_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) kfree_skb(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) struct ovs_net *ovs_net = net_generic(sock_net(skb->sk), ovs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) int skip = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) list_for_each_entry(dp, &ovs_net->dps, list_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) if (i >= skip &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) OVS_DP_CMD_GET) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) cb->args[0] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) [OVS_DP_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) [OVS_DP_ATTR_UPCALL_PID] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) [OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) [OVS_DP_ATTR_MASKS_CACHE_SIZE] = NLA_POLICY_RANGE(NLA_U32, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) PCPU_MIN_UNIT_SIZE / sizeof(struct mask_cache_entry)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) static const struct genl_small_ops dp_datapath_genl_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) { .cmd = OVS_DP_CMD_NEW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) .doit = ovs_dp_cmd_new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) { .cmd = OVS_DP_CMD_DEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) .doit = ovs_dp_cmd_del
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) { .cmd = OVS_DP_CMD_GET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) .flags = 0, /* OK for unprivileged users. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) .doit = ovs_dp_cmd_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) .dumpit = ovs_dp_cmd_dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) { .cmd = OVS_DP_CMD_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) .doit = ovs_dp_cmd_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) static struct genl_family dp_datapath_genl_family __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) .hdrsize = sizeof(struct ovs_header),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) .name = OVS_DATAPATH_FAMILY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) .version = OVS_DATAPATH_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) .maxattr = OVS_DP_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) .policy = datapath_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) .netnsok = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) .parallel_ops = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) .small_ops = dp_datapath_genl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) .n_small_ops = ARRAY_SIZE(dp_datapath_genl_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) .mcgrps = &ovs_dp_datapath_multicast_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) .n_mcgrps = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) /* Called with ovs_mutex or RCU read lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) struct net *net, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) u32 flags, u8 cmd, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) struct ovs_header *ovs_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) struct ovs_vport_stats vport_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) if (!ovs_header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) ovs_header->dp_ifindex = get_dpifindex(vport->dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) if (nla_put_u32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) nla_put_u32(skb, OVS_VPORT_ATTR_TYPE, vport->ops->type) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) nla_put_string(skb, OVS_VPORT_ATTR_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) ovs_vport_name(vport)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) nla_put_u32(skb, OVS_VPORT_ATTR_IFINDEX, vport->dev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) if (!net_eq(net, dev_net(vport->dev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) int id = peernet2id_alloc(net, dev_net(vport->dev), gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) if (nla_put_s32(skb, OVS_VPORT_ATTR_NETNSID, id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) ovs_vport_get_stats(vport, &vport_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) if (nla_put_64bit(skb, OVS_VPORT_ATTR_STATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) sizeof(struct ovs_vport_stats), &vport_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) OVS_VPORT_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) if (ovs_vport_get_upcall_portids(vport, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) err = ovs_vport_get_options(vport, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) if (err == -EMSGSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) genlmsg_end(skb, ovs_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) genlmsg_cancel(skb, ovs_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) static struct sk_buff *ovs_vport_cmd_alloc_info(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) return nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) /* Called with ovs_mutex, only via ovs_dp_notify_wq(). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) u32 portid, u32 seq, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) retval = ovs_vport_cmd_fill_info(vport, skb, net, portid, seq, 0, cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) BUG_ON(retval < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) /* Called with ovs_mutex or RCU read lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) static struct vport *lookup_vport(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) const struct ovs_header *ovs_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) struct nlattr *a[OVS_VPORT_ATTR_MAX + 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) if (a[OVS_VPORT_ATTR_IFINDEX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) return ERR_PTR(-EOPNOTSUPP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) if (a[OVS_VPORT_ATTR_NAME]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) vport = ovs_vport_locate(net, nla_data(a[OVS_VPORT_ATTR_NAME]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) if (!vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) if (ovs_header->dp_ifindex &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) ovs_header->dp_ifindex != get_dpifindex(vport->dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) return vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) } else if (a[OVS_VPORT_ATTR_PORT_NO]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) u32 port_no = nla_get_u32(a[OVS_VPORT_ATTR_PORT_NO]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) if (port_no >= DP_MAX_PORTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) return ERR_PTR(-EFBIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) dp = get_dp(net, ovs_header->dp_ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) if (!dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) vport = ovs_vport_ovsl_rcu(dp, port_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) if (!vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) return vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) static unsigned int ovs_get_max_headroom(struct datapath *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) unsigned int dev_headroom, max_headroom = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) hlist_for_each_entry_rcu(vport, &dp->ports[i], dp_hash_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) lockdep_ovsl_is_held()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) dev = vport->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) dev_headroom = netdev_get_fwd_headroom(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) if (dev_headroom > max_headroom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) max_headroom = dev_headroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) return max_headroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) /* Called with ovs_mutex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) static void ovs_update_headroom(struct datapath *dp, unsigned int new_headroom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) dp->max_headroom = new_headroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) hlist_for_each_entry_rcu(vport, &dp->ports[i], dp_hash_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) lockdep_ovsl_is_held())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) netdev_set_rx_headroom(vport->dev, new_headroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) struct nlattr **a = info->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) struct ovs_header *ovs_header = info->userhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) struct vport_parms parms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) struct sk_buff *reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) unsigned int new_headroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) u32 port_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) if (!a[OVS_VPORT_ATTR_NAME] || !a[OVS_VPORT_ATTR_TYPE] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) !a[OVS_VPORT_ATTR_UPCALL_PID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) if (a[OVS_VPORT_ATTR_IFINDEX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) port_no = a[OVS_VPORT_ATTR_PORT_NO]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) ? nla_get_u32(a[OVS_VPORT_ATTR_PORT_NO]) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) if (port_no >= DP_MAX_PORTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) return -EFBIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) reply = ovs_vport_cmd_alloc_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) if (!reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) if (!dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) goto exit_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) if (port_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) vport = ovs_vport_ovsl(dp, port_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) if (vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) goto exit_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) for (port_no = 1; ; port_no++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) if (port_no >= DP_MAX_PORTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) err = -EFBIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) goto exit_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) vport = ovs_vport_ovsl(dp, port_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) if (!vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) parms.name = nla_data(a[OVS_VPORT_ATTR_NAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) parms.type = nla_get_u32(a[OVS_VPORT_ATTR_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) parms.options = a[OVS_VPORT_ATTR_OPTIONS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) parms.dp = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) parms.port_no = port_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) parms.upcall_portids = a[OVS_VPORT_ATTR_UPCALL_PID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) vport = new_vport(&parms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) err = PTR_ERR(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) if (IS_ERR(vport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) if (err == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) goto exit_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) OVS_VPORT_CMD_NEW, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) new_headroom = netdev_get_fwd_headroom(vport->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) if (new_headroom > dp->max_headroom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) ovs_update_headroom(dp, new_headroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) netdev_set_rx_headroom(vport->dev, dp->max_headroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) BUG_ON(err < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) ovs_notify(&dp_vport_genl_family, reply, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) exit_unlock_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) kfree_skb(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) struct nlattr **a = info->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) struct sk_buff *reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) reply = ovs_vport_cmd_alloc_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) if (!reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) vport = lookup_vport(sock_net(skb->sk), info->userhdr, a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) err = PTR_ERR(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) if (IS_ERR(vport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) goto exit_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) if (a[OVS_VPORT_ATTR_TYPE] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) nla_get_u32(a[OVS_VPORT_ATTR_TYPE]) != vport->ops->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) goto exit_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) if (a[OVS_VPORT_ATTR_OPTIONS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) goto exit_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) if (a[OVS_VPORT_ATTR_UPCALL_PID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) struct nlattr *ids = a[OVS_VPORT_ATTR_UPCALL_PID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) err = ovs_vport_set_upcall_portids(vport, ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) goto exit_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) OVS_VPORT_CMD_SET, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) BUG_ON(err < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) ovs_notify(&dp_vport_genl_family, reply, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) exit_unlock_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) kfree_skb(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) bool update_headroom = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) struct nlattr **a = info->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) struct sk_buff *reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) unsigned int new_headroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) reply = ovs_vport_cmd_alloc_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) if (!reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) vport = lookup_vport(sock_net(skb->sk), info->userhdr, a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) err = PTR_ERR(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) if (IS_ERR(vport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) goto exit_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) if (vport->port_no == OVSP_LOCAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) goto exit_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) OVS_VPORT_CMD_DEL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) BUG_ON(err < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) /* the vport deletion may trigger dp headroom update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) dp = vport->dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) if (netdev_get_fwd_headroom(vport->dev) == dp->max_headroom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) update_headroom = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) netdev_reset_rx_headroom(vport->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) ovs_dp_detach_port(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) if (update_headroom) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) new_headroom = ovs_get_max_headroom(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) if (new_headroom < dp->max_headroom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) ovs_update_headroom(dp, new_headroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) ovs_notify(&dp_vport_genl_family, reply, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) exit_unlock_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) kfree_skb(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) static int ovs_vport_cmd_get(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) struct nlattr **a = info->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) struct ovs_header *ovs_header = info->userhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) struct sk_buff *reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) reply = ovs_vport_cmd_alloc_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) if (!reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) vport = lookup_vport(sock_net(skb->sk), ovs_header, a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) err = PTR_ERR(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) if (IS_ERR(vport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) goto exit_unlock_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) OVS_VPORT_CMD_GET, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) BUG_ON(err < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) return genlmsg_reply(reply, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) exit_unlock_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) kfree_skb(reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) static int ovs_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) struct ovs_header *ovs_header = genlmsg_data(nlmsg_data(cb->nlh));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) int bucket = cb->args[0], skip = cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) int i, j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) dp = get_dp_rcu(sock_net(skb->sk), ovs_header->dp_ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) if (!dp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) for (i = bucket; i < DP_VPORT_HASH_BUCKETS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) hlist_for_each_entry_rcu(vport, &dp->ports[i], dp_hash_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) if (j >= skip &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) ovs_vport_cmd_fill_info(vport, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) sock_net(skb->sk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) OVS_VPORT_CMD_GET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) GFP_ATOMIC) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) cb->args[0] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) cb->args[1] = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) static void ovs_dp_masks_rebalance(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) struct ovs_net *ovs_net = container_of(work, struct ovs_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) masks_rebalance.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) list_for_each_entry(dp, &ovs_net->dps, list_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) ovs_flow_masks_rebalance(&dp->table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) schedule_delayed_work(&ovs_net->masks_rebalance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) msecs_to_jiffies(DP_MASKS_REBALANCE_INTERVAL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) [OVS_VPORT_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) [OVS_VPORT_ATTR_STATS] = { .len = sizeof(struct ovs_vport_stats) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) [OVS_VPORT_ATTR_PORT_NO] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) [OVS_VPORT_ATTR_TYPE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) [OVS_VPORT_ATTR_UPCALL_PID] = { .type = NLA_UNSPEC },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) [OVS_VPORT_ATTR_IFINDEX] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) [OVS_VPORT_ATTR_NETNSID] = { .type = NLA_S32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) static const struct genl_small_ops dp_vport_genl_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) { .cmd = OVS_VPORT_CMD_NEW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) .doit = ovs_vport_cmd_new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) { .cmd = OVS_VPORT_CMD_DEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) .doit = ovs_vport_cmd_del
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) { .cmd = OVS_VPORT_CMD_GET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) .flags = 0, /* OK for unprivileged users. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) .doit = ovs_vport_cmd_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) .dumpit = ovs_vport_cmd_dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) { .cmd = OVS_VPORT_CMD_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) .doit = ovs_vport_cmd_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) struct genl_family dp_vport_genl_family __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) .hdrsize = sizeof(struct ovs_header),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) .name = OVS_VPORT_FAMILY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) .version = OVS_VPORT_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) .maxattr = OVS_VPORT_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) .policy = vport_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) .netnsok = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) .parallel_ops = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) .small_ops = dp_vport_genl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) .n_small_ops = ARRAY_SIZE(dp_vport_genl_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) .mcgrps = &ovs_dp_vport_multicast_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) .n_mcgrps = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) static struct genl_family * const dp_genl_families[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) &dp_datapath_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) &dp_vport_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) &dp_flow_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) &dp_packet_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) &dp_meter_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) #if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) &dp_ct_limit_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) static void dp_unregister_genl(int n_families)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) for (i = 0; i < n_families; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) genl_unregister_family(dp_genl_families[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) static int __init dp_register_genl(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) for (i = 0; i < ARRAY_SIZE(dp_genl_families); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) err = genl_register_family(dp_genl_families[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) dp_unregister_genl(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) static int __net_init ovs_init_net(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) INIT_LIST_HEAD(&ovs_net->dps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) INIT_WORK(&ovs_net->dp_notify_work, ovs_dp_notify_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) INIT_DELAYED_WORK(&ovs_net->masks_rebalance, ovs_dp_masks_rebalance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) err = ovs_ct_init(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) schedule_delayed_work(&ovs_net->masks_rebalance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) msecs_to_jiffies(DP_MASKS_REBALANCE_INTERVAL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) static void __net_exit list_vports_from_net(struct net *net, struct net *dnet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) struct datapath *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) list_for_each_entry(dp, &ovs_net->dps, list_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) struct vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) hlist_for_each_entry(vport, &dp->ports[i], dp_hash_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) if (vport->ops->type != OVS_VPORT_TYPE_INTERNAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) if (dev_net(vport->dev) == dnet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) list_add(&vport->detach_list, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) static void __net_exit ovs_exit_net(struct net *dnet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) struct datapath *dp, *dp_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) struct ovs_net *ovs_net = net_generic(dnet, ovs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) struct vport *vport, *vport_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) LIST_HEAD(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) ovs_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) ovs_ct_exit(dnet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) list_for_each_entry_safe(dp, dp_next, &ovs_net->dps, list_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) __dp_destroy(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) down_read(&net_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) for_each_net(net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) list_vports_from_net(net, dnet, &head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) up_read(&net_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) /* Detach all vports from given namespace. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) list_for_each_entry_safe(vport, vport_next, &head, detach_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) list_del(&vport->detach_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) ovs_dp_detach_port(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) ovs_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) cancel_delayed_work_sync(&ovs_net->masks_rebalance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) cancel_work_sync(&ovs_net->dp_notify_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) static struct pernet_operations ovs_net_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) .init = ovs_init_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) .exit = ovs_exit_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) .id = &ovs_net_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) .size = sizeof(struct ovs_net),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) static int __init dp_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) BUILD_BUG_ON(sizeof(struct ovs_skb_cb) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) sizeof_field(struct sk_buff, cb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) pr_info("Open vSwitch switching datapath\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) err = action_fifos_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) err = ovs_internal_dev_rtnl_link_register();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) goto error_action_fifos_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) err = ovs_flow_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) goto error_unreg_rtnl_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) err = ovs_vport_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) goto error_flow_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) err = register_pernet_device(&ovs_net_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) goto error_vport_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) err = register_netdevice_notifier(&ovs_dp_device_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) goto error_netns_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) err = ovs_netdev_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) goto error_unreg_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) err = dp_register_genl();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) goto error_unreg_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) error_unreg_netdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) ovs_netdev_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) error_unreg_notifier:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) unregister_netdevice_notifier(&ovs_dp_device_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) error_netns_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) unregister_pernet_device(&ovs_net_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) error_vport_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) ovs_vport_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) error_flow_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) ovs_flow_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) error_unreg_rtnl_link:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) ovs_internal_dev_rtnl_link_unregister();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) error_action_fifos_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) action_fifos_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) static void dp_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) dp_unregister_genl(ARRAY_SIZE(dp_genl_families));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) ovs_netdev_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) unregister_netdevice_notifier(&ovs_dp_device_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) unregister_pernet_device(&ovs_net_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) rcu_barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) ovs_vport_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) ovs_flow_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) ovs_internal_dev_rtnl_link_unregister();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) action_fifos_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) module_init(dp_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) module_exit(dp_cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) MODULE_DESCRIPTION("Open vSwitch switching datapath");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) MODULE_ALIAS_GENL_FAMILY(OVS_DATAPATH_FAMILY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) MODULE_ALIAS_GENL_FAMILY(OVS_VPORT_FAMILY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) MODULE_ALIAS_GENL_FAMILY(OVS_FLOW_FAMILY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) MODULE_ALIAS_GENL_FAMILY(OVS_PACKET_FAMILY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) MODULE_ALIAS_GENL_FAMILY(OVS_METER_FAMILY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) MODULE_ALIAS_GENL_FAMILY(OVS_CT_LIMIT_FAMILY);