Signed-off-by: Pravin B Shelar <pshe...@nicira.com> --- datapath/datapath.c | 50 ++++++++++++------------- datapath/linux/compat/include/linux/netlink.h | 6 +++ datapath/linux/compat/include/net/genetlink.h | 8 ++++ datapath/tunnel.c | 35 +++++++++-------- datapath/vport-capwap.c | 5 ++- 5 files changed, 63 insertions(+), 41 deletions(-)
diff --git a/datapath/datapath.c b/datapath/datapath.c index 65f4dc8..a28096e 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -61,8 +61,8 @@ #include "vport-internal_dev.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) || \ - LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) -#error Kernels before 2.6.18 or after 3.5 are not supported by this version of Open vSwitch. + LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) +#error Kernels before 2.6.18 or after 3.6 are not supported by this version of Open vSwitch. #endif #define REHASH_FLOW_INTERVAL (10 * 60 * HZ) @@ -1080,7 +1080,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info) /* Put flow in bucket. */ ovs_flow_tbl_insert(table, flow, &key, key_len); - reply = ovs_flow_cmd_build_info(flow, dp, info->snd_pid, + reply = ovs_flow_cmd_build_info(flow, dp, genl_info_port_id(info), info->snd_seq, OVS_FLOW_CMD_NEW); } else { @@ -1118,7 +1118,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info) ovs_flow_deferred_free_acts(old_acts); } - reply = ovs_flow_cmd_build_info(flow, dp, info->snd_pid, + reply = ovs_flow_cmd_build_info(flow, dp, genl_info_port_id(info), info->snd_seq, OVS_FLOW_CMD_NEW); /* Clear stats. */ @@ -1130,7 +1130,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info) } if (!IS_ERR(reply)) - genl_notify(reply, genl_info_net(info), info->snd_pid, + genl_notify(reply, genl_info_net(info), genl_info_port_id(info), ovs_dp_flow_multicast_group.id, info->nlhdr, GFP_KERNEL); else @@ -1171,7 +1171,7 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info) if (!flow) return -ENOENT; - reply = ovs_flow_cmd_build_info(flow, dp, info->snd_pid, + reply = ovs_flow_cmd_build_info(flow, dp, genl_info_port_id(info), info->snd_seq, OVS_FLOW_CMD_NEW); if (IS_ERR(reply)) return PTR_ERR(reply); @@ -1213,13 +1213,13 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info) ovs_flow_tbl_remove(table, flow); - err = ovs_flow_cmd_fill_info(flow, dp, reply, info->snd_pid, + err = ovs_flow_cmd_fill_info(flow, dp, reply, genl_info_port_id(info), info->snd_seq, 0, OVS_FLOW_CMD_DEL); BUG_ON(err < 0); ovs_flow_deferred_free(flow); - genl_notify(reply, genl_info_net(info), info->snd_pid, + genl_notify(reply, genl_info_net(info), genl_info_port_id(info), ovs_dp_flow_multicast_group.id, info->nlhdr, GFP_KERNEL); return 0; } @@ -1247,7 +1247,7 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) break; if (ovs_flow_cmd_fill_info(flow, dp, skb, - NETLINK_CB(cb->skb).pid, + NETLINK_CB_PORT_ID(cb->skb), cb->nlh->nlmsg_seq, NLM_F_MULTI, OVS_FLOW_CMD_NEW) < 0) break; @@ -1448,7 +1448,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) goto err_destroy_ports_array; } - reply = ovs_dp_cmd_build_info(dp, info->snd_pid, + reply = ovs_dp_cmd_build_info(dp, genl_info_port_id(info), info->snd_seq, OVS_DP_CMD_NEW); err = PTR_ERR(reply); if (IS_ERR(reply)) @@ -1460,7 +1460,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) rtnl_unlock(); - genl_notify(reply, genl_info_net(info), info->snd_pid, + genl_notify(reply, genl_info_net(info), genl_info_port_id(info), ovs_dp_datapath_multicast_group.id, info->nlhdr, GFP_KERNEL); return 0; @@ -1527,7 +1527,7 @@ static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info) if (IS_ERR(dp)) return err; - reply = ovs_dp_cmd_build_info(dp, info->snd_pid, + reply = ovs_dp_cmd_build_info(dp, genl_info_port_id(info), info->snd_seq, OVS_DP_CMD_DEL); err = PTR_ERR(reply); if (IS_ERR(reply)) @@ -1535,7 +1535,7 @@ static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info) __dp_destroy(dp); - genl_notify(reply, genl_info_net(info), info->snd_pid, + genl_notify(reply, genl_info_net(info), genl_info_port_id(info), ovs_dp_datapath_multicast_group.id, info->nlhdr, GFP_KERNEL); @@ -1556,7 +1556,7 @@ static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info) if (IS_ERR(dp)) return PTR_ERR(dp); - reply = ovs_dp_cmd_build_info(dp, info->snd_pid, + reply = ovs_dp_cmd_build_info(dp, genl_info_port_id(info), info->snd_seq, OVS_DP_CMD_NEW); if (IS_ERR(reply)) { err = PTR_ERR(reply); @@ -1565,7 +1565,7 @@ static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info) return 0; } - genl_notify(reply, genl_info_net(info), info->snd_pid, + genl_notify(reply, genl_info_net(info), genl_info_port_id(info), ovs_dp_datapath_multicast_group.id, info->nlhdr, GFP_KERNEL); @@ -1586,7 +1586,7 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info) if (IS_ERR(dp)) return PTR_ERR(dp); - reply = ovs_dp_cmd_build_info(dp, info->snd_pid, + reply = ovs_dp_cmd_build_info(dp, genl_info_port_id(info), info->snd_seq, OVS_DP_CMD_NEW); if (IS_ERR(reply)) return PTR_ERR(reply); @@ -1603,7 +1603,7 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) list_for_each_entry(dp, &ovs_net->dps, list_node) { if (i >= skip && - ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).pid, + ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB_PORT_ID(cb->skb), cb->nlh->nlmsg_seq, NLM_F_MULTI, OVS_DP_CMD_NEW) < 0) break; @@ -1848,7 +1848,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) err = change_vport(vport, a); if (!err) { - reply = ovs_vport_cmd_build_info(vport, info->snd_pid, + reply = ovs_vport_cmd_build_info(vport, genl_info_port_id(info), info->snd_seq, OVS_VPORT_CMD_NEW); if (IS_ERR(reply)) @@ -1858,7 +1858,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) ovs_dp_detach_port(vport); goto exit_unlock; } - genl_notify(reply, genl_info_net(info), info->snd_pid, + genl_notify(reply, genl_info_net(info), genl_info_port_id(info), ovs_dp_vport_multicast_group.id, info->nlhdr, GFP_KERNEL); exit_unlock: @@ -1898,7 +1898,7 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info) if (!err && a[OVS_VPORT_ATTR_UPCALL_PID]) vport->upcall_pid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]); - reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq, + reply = ovs_vport_cmd_build_info(vport, genl_info_port_id(info), info->snd_seq, OVS_VPORT_CMD_NEW); if (IS_ERR(reply)) { netlink_set_err(GENL_SOCK(sock_net(skb->sk)), 0, @@ -1906,7 +1906,7 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info) goto exit_unlock; } - genl_notify(reply, genl_info_net(info), info->snd_pid, + genl_notify(reply, genl_info_net(info), genl_info_port_id(info), ovs_dp_vport_multicast_group.id, info->nlhdr, GFP_KERNEL); exit_unlock: @@ -1937,7 +1937,7 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info) goto exit_unlock; } - reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq, + reply = ovs_vport_cmd_build_info(vport, genl_info_port_id(info), info->snd_seq, OVS_VPORT_CMD_DEL); err = PTR_ERR(reply); if (IS_ERR(reply)) @@ -1945,7 +1945,7 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info) ovs_dp_detach_port(vport); - genl_notify(reply, genl_info_net(info), info->snd_pid, + genl_notify(reply, genl_info_net(info), genl_info_port_id(info), ovs_dp_vport_multicast_group.id, info->nlhdr, GFP_KERNEL); exit_unlock: @@ -1972,7 +1972,7 @@ static int ovs_vport_cmd_get(struct sk_buff *skb, struct genl_info *info) if (IS_ERR(vport)) goto exit_unlock; - reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq, + reply = ovs_vport_cmd_build_info(vport, genl_info_port_id(info), info->snd_seq, OVS_VPORT_CMD_NEW); err = PTR_ERR(reply); if (IS_ERR(reply)) @@ -2008,7 +2008,7 @@ static int ovs_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) hlist_for_each_entry_rcu(vport, n, &dp->ports[i], dp_hash_node) { if (j >= skip && ovs_vport_cmd_fill_info(vport, skb, - NETLINK_CB(cb->skb).pid, + NETLINK_CB_PORT_ID(cb->skb), cb->nlh->nlmsg_seq, NLM_F_MULTI, OVS_VPORT_CMD_NEW) < 0) diff --git a/datapath/linux/compat/include/linux/netlink.h b/datapath/linux/compat/include/linux/netlink.h index 44a2073..73af1cb 100644 --- a/datapath/linux/compat/include/linux/netlink.h +++ b/datapath/linux/compat/include/linux/netlink.h @@ -32,4 +32,10 @@ static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb) } #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) +#define NETLINK_CB_PORT_ID(skb) (NETLINK_CB((skb)).portid) +#else +#define NETLINK_CB_PORT_ID(skb) (NETLINK_CB((skb)).pid) +#endif + #endif diff --git a/datapath/linux/compat/include/net/genetlink.h b/datapath/linux/compat/include/net/genetlink.h index af7d5fd..a4fc431 100644 --- a/datapath/linux/compat/include/net/genetlink.h +++ b/datapath/linux/compat/include/net/genetlink.h @@ -171,6 +171,14 @@ static inline struct net *genl_info_net(struct genl_info *info) } #endif +static inline u32 genl_info_port_id(struct genl_info *info) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) + return info->snd_portid; +#else + return info->snd_pid; +#endif +} #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) #define genlmsg_unicast(ignore_net, skb, pid) genlmsg_unicast(skb, pid) #endif diff --git a/datapath/tunnel.c b/datapath/tunnel.c index 5b74877..04ff55f 100644 --- a/datapath/tunnel.c +++ b/datapath/tunnel.c @@ -701,32 +701,35 @@ static bool check_mtu(struct sk_buff *skb, return true; } -static struct rtable *find_route(const struct tnl_mutable_config *mutable, - __be32 saddr, __be32 daddr, u8 ipproto, - u8 tos) +static struct rtable *find_route(struct net *net, + __be32 *saddr, __be32 daddr, u8 ipproto, + u8 tos) { + struct rtable *rt; /* Tunnel configuration keeps DSCP part of TOS bits, But Linux * router expect RT_TOS bits only. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) struct flowi fl = { .nl_u = { .ip4_u = { .daddr = daddr, - .saddr = saddr, + .saddr = *saddr, .tos = RT_TOS(tos) } }, .proto = ipproto }; - struct rtable *rt; - if (unlikely(ip_route_output_key(port_key_get_net(&mutable->key), &rt, &fl))) + if (unlikely(ip_route_output_key(net, &rt, &fl))) return ERR_PTR(-EADDRNOTAVAIL); - + *saddr = fl.nl_u.ip4_u.saddr; return rt; #else struct flowi4 fl = { .daddr = daddr, - .saddr = saddr, + .saddr = *saddr, .flowi4_tos = RT_TOS(tos), .flowi4_proto = ipproto }; - return ip_route_output_key(port_key_get_net(&mutable->key), &fl); + rt = ip_route_output_key(net, &fl); + if (!IS_ERR(rt)) + *saddr = fl.saddr; + return rt; #endif } @@ -947,7 +950,8 @@ int ovs_tnl_send(struct vport *vport, struct sk_buff *skb) } /* Route lookup */ - rt = find_route(mutable, saddr, daddr, tnl_vport->tnl_ops->ipproto, tos); + rt = find_route(port_key_get_net(&mutable->key), &saddr, daddr, + tnl_vport->tnl_ops->ipproto, tos); if (IS_ERR(rt)) goto error_free; @@ -1007,10 +1011,9 @@ int ovs_tnl_send(struct vport *vport, struct sk_buff *skb) iph = ip_hdr(skb); iph->version = 4; iph->ihl = sizeof(struct iphdr) >> 2; - iph->frag_off = htons(IP_DF); iph->protocol = tnl_vport->tnl_ops->ipproto; - iph->daddr = rt->rt_dst; - iph->saddr = rt->rt_src; + iph->daddr = daddr; + iph->saddr = saddr; iph->tos = tos; iph->ttl = ttl; iph->frag_off = frag_off; @@ -1106,9 +1109,11 @@ static int tnl_set_config(struct net *net, struct nlattr *options, if (ipv4_is_multicast(mutable->key.daddr)) { struct net_device *dev; struct rtable *rt; + __be32 saddr = mutable->key.saddr; - rt = find_route(mutable, mutable->key.saddr, mutable->key.daddr, - tnl_ops->ipproto, mutable->tos); + rt = find_route(port_key_get_net(&mutable->key), + &saddr, mutable->key.daddr, + tnl_ops->ipproto, mutable->tos); if (IS_ERR(rt)) return -EADDRNOTAVAIL; dev = rt_dst(rt).dev; diff --git a/datapath/vport-capwap.c b/datapath/vport-capwap.c index e466323..83c4b03 100644 --- a/datapath/vport-capwap.c +++ b/datapath/vport-capwap.c @@ -791,8 +791,11 @@ static struct sk_buff *defrag(struct sk_buff *skb, bool frag_last) struct frag_queue *fq; if (atomic_read(&ns_frag_state->mem) > ns_frag_state->high_thresh) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) + inet_frag_evictor(ns_frag_state, &frag_state, true); +#else inet_frag_evictor(ns_frag_state, &frag_state); - +#endif match.daddr = iph->daddr; match.saddr = iph->saddr; match.id = cwh->frag_id; -- 1.7.10 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev