blob: 04e22a45c2e4d20303a9844cda9f27197c09dc39 [file] [log] [blame]
developer267a3de2022-07-15 15:48:26 +08001Index: net/openvswitch/vport-internal_dev.c
2===================================================================
3--- a/net/openvswitch/vport-internal_dev.c
4+++ b/net/openvswitch/vport-internal_dev.c
5@@ -113,12 +113,58 @@ internal_get_stats(struct net_device *de
6 }
7 }
8
9+static int internal_dev_fill_forward_path(struct net_device_path_ctx *ctx, struct net_device_path *path)
10+{
11+ struct vport *vport;
12+ int i;
13+ struct table_instance *ti;
14+ struct datapath *dp;
15+ struct sw_flow_key *key;
16+ struct sw_flow_actions *sf_acts;
17+ struct nlattr *a;
18+ int rem;
19+
20+ vport = ovs_internal_dev_get_vport(ctx->dev);
21+ dp = vport->dp;
22+ ti = rcu_dereference_ovsl(dp->table.ti);
23+
24+ for (i = 0; i < ti->n_buckets; i++) {
25+ struct sw_flow *flow;
26+ struct hlist_head *head = &ti->buckets[i];
27+ struct hlist_node *n;
28+
29+ hlist_for_each_entry_safe(flow, n, head, flow_table.node[ti->node_ver]) {
30+ key = &flow->key;
31+
32+ if((!memcmp(ctx->dev->dev_addr, key->eth.dst, ETH_ALEN)) && (!memcmp(ctx->daddr, key->eth.src, ETH_ALEN))){
33+ sf_acts = rcu_dereference_ovsl(flow->sf_acts);
34+ for (a = sf_acts->actions, rem = sf_acts->actions_len; rem > 0;
35+ a = nla_next(a, &rem)) {
36+ if(nla_type(a) == OVS_ACTION_ATTR_OUTPUT){
37+ vport = ovs_vport_rcu(dp, key->phy.in_port);
38+ goto out;
39+ }
40+ }
41+ }
42+ }
43+ }
44+
45+out:
46+
47+ path->type = DEV_PATH_BRIDGE;
48+ path->dev = ctx->dev;
49+ ctx->dev = vport->dev;
50+
51+ return 0;
52+}
53+
54 static const struct net_device_ops internal_dev_netdev_ops = {
55 .ndo_open = internal_dev_open,
56 .ndo_stop = internal_dev_stop,
57 .ndo_start_xmit = internal_dev_xmit,
58 .ndo_set_mac_address = eth_mac_addr,
59 .ndo_get_stats64 = internal_get_stats,
60+ .ndo_fill_forward_path = internal_dev_fill_forward_path,
61 };
62
63 static struct rtnl_link_ops internal_dev_link_ops __read_mostly = {