summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-06-19 18:07:49 -0700
committerDavid S. Miller <davem@davemloft.net>2013-06-19 18:07:49 -0700
commitdc3d807d6fd983603c82e7bcdbaa49cdb4239691 (patch)
treef426945de6694203f2c34218b4e4b06913b8f58c /include
parentac8025a643a0e0beb81f3f37ca693364c6b77858 (diff)
parentaa310701e787087dbfbccf1409982a96e16c57a6 (diff)
openvswitch: gre tunneling support.
Pravin B Shelar says: ==================== Following patch series adds support for gre tunneling. First six patches extend kernel gre and ip_tunnel modules api so that there is more code sharing between gre modules and ovs. Rest of patches adds ovs tunneling infrastructre and gre protocol vport. V2 fixes two patches according to comments from Jesse. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/net/gre.h27
-rw-r--r--include/net/ip_tunnels.h28
-rw-r--r--include/uapi/linux/openvswitch.h19
3 files changed, 63 insertions, 11 deletions
diff --git a/include/net/gre.h b/include/net/gre.h
index 9f03a390c826..a5a4ddf05300 100644
--- a/include/net/gre.h
+++ b/include/net/gre.h
@@ -7,6 +7,7 @@
#define GREPROTO_CISCO 0
#define GREPROTO_PPTP 1
#define GREPROTO_MAX 2
+#define GRE_IP_PROTO_MAX 2
struct gre_protocol {
int (*handler)(struct sk_buff *skb);
@@ -22,6 +23,32 @@ struct gre_base_hdr {
int gre_add_protocol(const struct gre_protocol *proto, u8 version);
int gre_del_protocol(const struct gre_protocol *proto, u8 version);
+struct gre_cisco_protocol {
+ int (*handler)(struct sk_buff *skb, const struct tnl_ptk_info *tpi);
+ int (*err_handler)(struct sk_buff *skb, u32 info,
+ const struct tnl_ptk_info *tpi);
+ u8 priority;
+};
+
+int gre_cisco_register(struct gre_cisco_protocol *proto);
+int gre_cisco_unregister(struct gre_cisco_protocol *proto);
+void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
+ int hdr_len);
+struct sk_buff *gre_handle_offloads(struct sk_buff *skb, bool gre_csum);
+
+static inline int ip_gre_calc_hlen(__be16 o_flags)
+{
+ int addend = 4;
+
+ if (o_flags&TUNNEL_CSUM)
+ addend += 4;
+ if (o_flags&TUNNEL_KEY)
+ addend += 4;
+ if (o_flags&TUNNEL_SEQ)
+ addend += 4;
+ return addend;
+}
+
static inline __be16 gre_flags_to_tnl_flags(__be16 flags)
{
__be16 tflags = 0;
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 1be442f89406..10bbb4273f7d 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -73,6 +73,7 @@ struct ip_tunnel {
#define TUNNEL_REC __cpu_to_be16(0x20)
#define TUNNEL_VERSION __cpu_to_be16(0x40)
#define TUNNEL_NO_KEY __cpu_to_be16(0x80)
+#define TUNNEL_DONT_FRAGMENT __cpu_to_be16(0x0100)
struct tnl_ptk_info {
__be16 flags;
@@ -155,23 +156,28 @@ static inline void tunnel_ip_select_ident(struct sk_buff *skb,
(skb_shinfo(skb)->gso_segs ?: 1) - 1);
}
-static inline void iptunnel_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- int err;
- int pkt_len = skb->len - skb_transport_offset(skb);
- struct pcpu_tstats *tstats = this_cpu_ptr(dev->tstats);
+int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto);
+int iptunnel_xmit(struct net *net, struct rtable *rt,
+ struct sk_buff *skb,
+ __be32 src, __be32 dst, __u8 proto,
+ __u8 tos, __u8 ttl, __be16 df);
- nf_reset(skb);
+static inline void iptunnel_xmit_stats(int err,
+ struct net_device_stats *err_stats,
+ struct pcpu_tstats __percpu *stats)
+{
+ if (err > 0) {
+ struct pcpu_tstats *tstats = this_cpu_ptr(stats);
- err = ip_local_out(skb);
- if (likely(net_xmit_eval(err) == 0)) {
u64_stats_update_begin(&tstats->syncp);
- tstats->tx_bytes += pkt_len;
+ tstats->tx_bytes += err;
tstats->tx_packets++;
u64_stats_update_end(&tstats->syncp);
+ } else if (err < 0) {
+ err_stats->tx_errors++;
+ err_stats->tx_aborted_errors++;
} else {
- dev->stats.tx_errors++;
- dev->stats.tx_aborted_errors++;
+ err_stats->tx_dropped++;
}
}
#endif /* __NET_IP_TUNNELS_H */
diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h
index 424672db7f12..c55efaaa9bb4 100644
--- a/include/uapi/linux/openvswitch.h
+++ b/include/uapi/linux/openvswitch.h
@@ -164,6 +164,7 @@ enum ovs_vport_type {
OVS_VPORT_TYPE_UNSPEC,
OVS_VPORT_TYPE_NETDEV, /* network device */
OVS_VPORT_TYPE_INTERNAL, /* network device implemented by datapath */
+ OVS_VPORT_TYPE_GRE, /* GRE tunnel. */
__OVS_VPORT_TYPE_MAX
};
@@ -246,11 +247,29 @@ enum ovs_key_attr {
OVS_KEY_ATTR_ARP, /* struct ovs_key_arp */
OVS_KEY_ATTR_ND, /* struct ovs_key_nd */
OVS_KEY_ATTR_SKB_MARK, /* u32 skb mark */
+ OVS_KEY_ATTR_TUNNEL, /* Nested set of ovs_tunnel attributes */
+
+#ifdef __KERNEL__
+ OVS_KEY_ATTR_IPV4_TUNNEL, /* struct ovs_key_ipv4_tunnel */
+#endif
__OVS_KEY_ATTR_MAX
};
#define OVS_KEY_ATTR_MAX (__OVS_KEY_ATTR_MAX - 1)
+enum ovs_tunnel_key_attr {
+ OVS_TUNNEL_KEY_ATTR_ID, /* be64 Tunnel ID */
+ OVS_TUNNEL_KEY_ATTR_IPV4_SRC, /* be32 src IP address. */
+ OVS_TUNNEL_KEY_ATTR_IPV4_DST, /* be32 dst IP address. */
+ OVS_TUNNEL_KEY_ATTR_TOS, /* u8 Tunnel IP ToS. */
+ OVS_TUNNEL_KEY_ATTR_TTL, /* u8 Tunnel IP TTL. */
+ OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT, /* No argument, set DF. */
+ OVS_TUNNEL_KEY_ATTR_CSUM, /* No argument. CSUM packet. */
+ __OVS_TUNNEL_KEY_ATTR_MAX
+};
+
+#define OVS_TUNNEL_KEY_ATTR_MAX (__OVS_TUNNEL_KEY_ATTR_MAX - 1)
+
/**
* enum ovs_frag_type - IPv4 and IPv6 fragment type
* @OVS_FRAG_TYPE_NONE: Packet is not a fragment.