aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-06-27 16:22:38 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-29 19:57:53 -0400
commit576a30eb6453439b3c37ba24455ac7090c247b5a (patch)
treee0c427a61e3de5c93e797c09903d910f6f060e64 /include
parent68c1692e3ea5d79f24cb5cc566c4a73939d13d25 (diff)
[NET]: Added GSO header verification
When GSO packets come from an untrusted source (e.g., a Xen guest domain), we need to verify the header integrity before passing it to the hardware. Since the first step in GSO is to verify the header, we can reuse that code by adding a new bit to gso_type: SKB_GSO_DODGY. Packets with this bit set can only be fed directly to devices with the corresponding bit NETIF_F_GSO_ROBUST. If the device doesn't have that bit, then the skb is fed to the GSO engine which will allow the packet to be sent to the hardware if it passes the header check. This patch changes the sg flag to a full features flag. The same method can be used to implement TSO ECN support. We simply have to mark packets with CWR set with SKB_GSO_ECN so that only hardware with a corresponding NETIF_F_TSO_ECN can accept them. The GSO engine can either fully segment the packet, or segment the first MTU and pass the rest to the hardware for further segmentation. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/linux/netdevice.h17
-rw-r--r--include/linux/skbuff.h5
-rw-r--r--include/net/protocol.h3
-rw-r--r--include/net/tcp.h2
4 files changed, 19 insertions, 8 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 03cd7551a7a1..84b0f0d16fcb 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -315,6 +315,7 @@ struct net_device
315#define NETIF_F_GSO_SHIFT 16 315#define NETIF_F_GSO_SHIFT 16
316#define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT) 316#define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
317#define NETIF_F_UFO (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT) 317#define NETIF_F_UFO (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT)
318#define NETIF_F_GSO_ROBUST (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
318 319
319#define NETIF_F_GEN_CSUM (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM) 320#define NETIF_F_GEN_CSUM (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
320#define NETIF_F_ALL_CSUM (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM) 321#define NETIF_F_ALL_CSUM (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM)
@@ -543,7 +544,8 @@ struct packet_type {
543 struct net_device *, 544 struct net_device *,
544 struct packet_type *, 545 struct packet_type *,
545 struct net_device *); 546 struct net_device *);
546 struct sk_buff *(*gso_segment)(struct sk_buff *skb, int sg); 547 struct sk_buff *(*gso_segment)(struct sk_buff *skb,
548 int features);
547 void *af_packet_priv; 549 void *af_packet_priv;
548 struct list_head list; 550 struct list_head list;
549}; 551};
@@ -968,7 +970,7 @@ extern int netdev_max_backlog;
968extern int weight_p; 970extern int weight_p;
969extern int netdev_set_master(struct net_device *dev, struct net_device *master); 971extern int netdev_set_master(struct net_device *dev, struct net_device *master);
970extern int skb_checksum_help(struct sk_buff *skb, int inward); 972extern int skb_checksum_help(struct sk_buff *skb, int inward);
971extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int sg); 973extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features);
972#ifdef CONFIG_BUG 974#ifdef CONFIG_BUG
973extern void netdev_rx_csum_fault(struct net_device *dev); 975extern void netdev_rx_csum_fault(struct net_device *dev);
974#else 976#else
@@ -988,11 +990,16 @@ extern void dev_seq_stop(struct seq_file *seq, void *v);
988 990
989extern void linkwatch_run_queue(void); 991extern void linkwatch_run_queue(void);
990 992
993static inline int skb_gso_ok(struct sk_buff *skb, int features)
994{
995 int feature = skb_shinfo(skb)->gso_size ?
996 skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0;
997 return (features & feature) != feature;
998}
999
991static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) 1000static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
992{ 1001{
993 int feature = skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT; 1002 return skb_gso_ok(skb, dev->features);
994 return skb_shinfo(skb)->gso_size &&
995 (dev->features & feature) != feature;
996} 1003}
997 1004
998#endif /* __KERNEL__ */ 1005#endif /* __KERNEL__ */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 16eef03ce0eb..5fb72da7da03 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -172,6 +172,9 @@ enum {
172enum { 172enum {
173 SKB_GSO_TCPV4 = 1 << 0, 173 SKB_GSO_TCPV4 = 1 << 0,
174 SKB_GSO_UDPV4 = 1 << 1, 174 SKB_GSO_UDPV4 = 1 << 1,
175
176 /* This indicates the skb is from an untrusted source. */
177 SKB_GSO_DODGY = 1 << 2,
175}; 178};
176 179
177/** 180/**
@@ -1299,7 +1302,7 @@ extern void skb_split(struct sk_buff *skb,
1299 struct sk_buff *skb1, const u32 len); 1302 struct sk_buff *skb1, const u32 len);
1300 1303
1301extern void skb_release_data(struct sk_buff *skb); 1304extern void skb_release_data(struct sk_buff *skb);
1302extern struct sk_buff *skb_segment(struct sk_buff *skb, int sg); 1305extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
1303 1306
1304static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, 1307static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
1305 int len, void *buffer) 1308 int len, void *buffer)
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 3b6dc15c68a5..40b6b9c9973f 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -36,7 +36,8 @@
36struct net_protocol { 36struct net_protocol {
37 int (*handler)(struct sk_buff *skb); 37 int (*handler)(struct sk_buff *skb);
38 void (*err_handler)(struct sk_buff *skb, u32 info); 38 void (*err_handler)(struct sk_buff *skb, u32 info);
39 struct sk_buff *(*gso_segment)(struct sk_buff *skb, int sg); 39 struct sk_buff *(*gso_segment)(struct sk_buff *skb,
40 int features);
40 int no_policy; 41 int no_policy;
41}; 42};
42 43
diff --git a/include/net/tcp.h b/include/net/tcp.h
index ca3d38dfc00b..624921e76332 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1086,7 +1086,7 @@ extern struct request_sock_ops tcp_request_sock_ops;
1086 1086
1087extern int tcp_v4_destroy_sock(struct sock *sk); 1087extern int tcp_v4_destroy_sock(struct sock *sk);
1088 1088
1089extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int sg); 1089extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features);
1090 1090
1091#ifdef CONFIG_PROC_FS 1091#ifdef CONFIG_PROC_FS
1092extern int tcp4_proc_init(void); 1092extern int tcp4_proc_init(void);