mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-06 14:05:39 +00:00
inet: generalize ipv4-only RFC3168 5.3 ecn fragmentation handling for future use by ipv6
This patch just moves some code arround to make the ip4_frag_ecn_table and IPFRAG_ECN_* constants accessible from the other reassembly engines. I also renamed ip4_frag_ecn_table to ip_frag_ecn_table. Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: Jesper Dangaard Brouer <jbrouer@redhat.com> Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
63998ac24f
commit
be991971d5
@ -153,4 +153,16 @@ static inline void inet_frag_lru_add(struct netns_frags *nf,
|
||||
list_add_tail(&q->lru_list, &nf->lru_list);
|
||||
spin_unlock(&nf->lru_lock);
|
||||
}
|
||||
|
||||
/* RFC 3168 support :
|
||||
* We want to check ECN values of all fragments, do detect invalid combinations.
|
||||
* In ipq->ecn, we store the OR value of each ip4_frag_ecn() fragment value.
|
||||
*/
|
||||
#define IPFRAG_ECN_NOT_ECT 0x01 /* one frag had ECN_NOT_ECT */
|
||||
#define IPFRAG_ECN_ECT_1 0x02 /* one frag had ECN_ECT_1 */
|
||||
#define IPFRAG_ECN_ECT_0 0x04 /* one frag had ECN_ECT_0 */
|
||||
#define IPFRAG_ECN_CE 0x08 /* one frag had ECN_CE */
|
||||
|
||||
extern const u8 ip_frag_ecn_table[16];
|
||||
|
||||
#endif
|
||||
|
@ -23,6 +23,28 @@
|
||||
|
||||
#include <net/sock.h>
|
||||
#include <net/inet_frag.h>
|
||||
#include <net/inet_ecn.h>
|
||||
|
||||
/* Given the OR values of all fragments, apply RFC 3168 5.3 requirements
|
||||
* Value : 0xff if frame should be dropped.
|
||||
* 0 or INET_ECN_CE value, to be ORed in to final iph->tos field
|
||||
*/
|
||||
const u8 ip_frag_ecn_table[16] = {
|
||||
/* at least one fragment had CE, and others ECT_0 or ECT_1 */
|
||||
[IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0] = INET_ECN_CE,
|
||||
[IPFRAG_ECN_CE | IPFRAG_ECN_ECT_1] = INET_ECN_CE,
|
||||
[IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = INET_ECN_CE,
|
||||
|
||||
/* invalid combinations : drop frame */
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE] = 0xff,
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_0] = 0xff,
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_1] = 0xff,
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = 0xff,
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0] = 0xff,
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_1] = 0xff,
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = 0xff,
|
||||
};
|
||||
EXPORT_SYMBOL(ip_frag_ecn_table);
|
||||
|
||||
static void inet_frag_secret_rebuild(unsigned long dummy)
|
||||
{
|
||||
|
@ -79,40 +79,11 @@ struct ipq {
|
||||
struct inet_peer *peer;
|
||||
};
|
||||
|
||||
/* RFC 3168 support :
|
||||
* We want to check ECN values of all fragments, do detect invalid combinations.
|
||||
* In ipq->ecn, we store the OR value of each ip4_frag_ecn() fragment value.
|
||||
*/
|
||||
#define IPFRAG_ECN_NOT_ECT 0x01 /* one frag had ECN_NOT_ECT */
|
||||
#define IPFRAG_ECN_ECT_1 0x02 /* one frag had ECN_ECT_1 */
|
||||
#define IPFRAG_ECN_ECT_0 0x04 /* one frag had ECN_ECT_0 */
|
||||
#define IPFRAG_ECN_CE 0x08 /* one frag had ECN_CE */
|
||||
|
||||
static inline u8 ip4_frag_ecn(u8 tos)
|
||||
{
|
||||
return 1 << (tos & INET_ECN_MASK);
|
||||
}
|
||||
|
||||
/* Given the OR values of all fragments, apply RFC 3168 5.3 requirements
|
||||
* Value : 0xff if frame should be dropped.
|
||||
* 0 or INET_ECN_CE value, to be ORed in to final iph->tos field
|
||||
*/
|
||||
static const u8 ip4_frag_ecn_table[16] = {
|
||||
/* at least one fragment had CE, and others ECT_0 or ECT_1 */
|
||||
[IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0] = INET_ECN_CE,
|
||||
[IPFRAG_ECN_CE | IPFRAG_ECN_ECT_1] = INET_ECN_CE,
|
||||
[IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = INET_ECN_CE,
|
||||
|
||||
/* invalid combinations : drop frame */
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE] = 0xff,
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_0] = 0xff,
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_1] = 0xff,
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = 0xff,
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0] = 0xff,
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_1] = 0xff,
|
||||
[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = 0xff,
|
||||
};
|
||||
|
||||
static struct inet_frags ip4_frags;
|
||||
|
||||
int ip_frag_nqueues(struct net *net)
|
||||
@ -551,7 +522,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
|
||||
|
||||
ipq_kill(qp);
|
||||
|
||||
ecn = ip4_frag_ecn_table[qp->ecn];
|
||||
ecn = ip_frag_ecn_table[qp->ecn];
|
||||
if (unlikely(ecn == 0xff)) {
|
||||
err = -EINVAL;
|
||||
goto out_fail;
|
||||
|
Loading…
Reference in New Issue
Block a user