Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[NETFILTER]: xt_conntrack: add port and direction matching

Extend the xt_conntrack match revision 1 by port matching (all four
{orig,repl}{src,dst}) and by packet direction matching.

Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jan Engelhardt and committed by
David S. Miller
b4164998 41d0cded

+63 -17
+18 -12
include/linux/netfilter/xt_conntrack.h
··· 6 6 #define _XT_CONNTRACK_H 7 7 8 8 #include <linux/netfilter/nf_conntrack_tuple_common.h> 9 - #ifdef __KERNEL__ 10 - # include <linux/in.h> 11 - #endif 12 9 13 10 #define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) 14 11 #define XT_CONNTRACK_STATE_INVALID (1 << 0) ··· 15 18 #define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3)) 16 19 17 20 /* flags, invflags: */ 18 - #define XT_CONNTRACK_STATE 0x01 19 - #define XT_CONNTRACK_PROTO 0x02 20 - #define XT_CONNTRACK_ORIGSRC 0x04 21 - #define XT_CONNTRACK_ORIGDST 0x08 22 - #define XT_CONNTRACK_REPLSRC 0x10 23 - #define XT_CONNTRACK_REPLDST 0x20 24 - #define XT_CONNTRACK_STATUS 0x40 25 - #define XT_CONNTRACK_EXPIRES 0x80 21 + enum { 22 + XT_CONNTRACK_STATE = 1 << 0, 23 + XT_CONNTRACK_PROTO = 1 << 1, 24 + XT_CONNTRACK_ORIGSRC = 1 << 2, 25 + XT_CONNTRACK_ORIGDST = 1 << 3, 26 + XT_CONNTRACK_REPLSRC = 1 << 4, 27 + XT_CONNTRACK_REPLDST = 1 << 5, 28 + XT_CONNTRACK_STATUS = 1 << 6, 29 + XT_CONNTRACK_EXPIRES = 1 << 7, 30 + XT_CONNTRACK_ORIGSRC_PORT = 1 << 8, 31 + XT_CONNTRACK_ORIGDST_PORT = 1 << 9, 32 + XT_CONNTRACK_REPLSRC_PORT = 1 << 10, 33 + XT_CONNTRACK_REPLDST_PORT = 1 << 11, 34 + XT_CONNTRACK_DIRECTION = 1 << 12, 35 + }; 26 36 27 37 /* This is exposed to userspace, so remains frozen in time. */ 28 38 struct ip_conntrack_old_tuple ··· 74 70 union nf_inet_addr repldst_addr, repldst_mask; 75 71 u_int32_t expires_min, expires_max; 76 72 u_int16_t l4proto; 73 + __be16 origsrc_port, origdst_port; 74 + __be16 replsrc_port, repldst_port; 75 + u_int16_t match_flags, invert_flags; 77 76 u_int8_t state_mask, status_mask; 78 - u_int8_t match_flags, invert_flags; 79 77 }; 80 78 81 79 #endif /*_XT_CONNTRACK_H*/
+45 -5
net/netfilter/xt_conntrack.c
··· 4 4 * 5 5 * (C) 2001 Marc Boucher (marc@mbsi.ca). 6 6 * Copyright © CC Computer Consultants GmbH, 2007 - 2008 7 - * Jan Engelhardt <jengelh@computergmbh.de> 8 7 * 9 8 * This program is free software; you can redistribute it and/or modify 10 9 * it under the terms of the GNU General Public License version 2 as ··· 19 20 20 21 MODULE_LICENSE("GPL"); 21 22 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 23 + MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); 22 24 MODULE_DESCRIPTION("Xtables: connection tracking state match"); 23 25 MODULE_ALIAS("ipt_conntrack"); 24 26 MODULE_ALIAS("ip6t_conntrack"); ··· 166 166 &info->repldst_addr, &info->repldst_mask, family); 167 167 } 168 168 169 + static inline bool 170 + ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info, 171 + const struct nf_conn *ct) 172 + { 173 + const struct nf_conntrack_tuple *tuple; 174 + 175 + tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; 176 + if ((info->match_flags & XT_CONNTRACK_PROTO) && 177 + (tuple->dst.protonum == info->l4proto) ^ 178 + !(info->invert_flags & XT_CONNTRACK_PROTO)) 179 + return false; 180 + 181 + /* Shortcut to match all recognized protocols by using ->src.all. */ 182 + if ((info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) && 183 + (tuple->src.u.all == info->origsrc_port) ^ 184 + !(info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT)) 185 + return false; 186 + 187 + if ((info->match_flags & XT_CONNTRACK_ORIGDST_PORT) && 188 + (tuple->dst.u.all == info->origdst_port) ^ 189 + !(info->invert_flags & XT_CONNTRACK_ORIGDST_PORT)) 190 + return false; 191 + 192 + tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; 193 + 194 + if ((info->match_flags & XT_CONNTRACK_REPLSRC_PORT) && 195 + (tuple->src.u.all == info->replsrc_port) ^ 196 + !(info->invert_flags & XT_CONNTRACK_REPLSRC_PORT)) 197 + return false; 198 + 199 + if ((info->match_flags & XT_CONNTRACK_REPLDST_PORT) && 200 + (tuple->dst.u.all == info->repldst_port) ^ 201 + !(info->invert_flags & XT_CONNTRACK_REPLDST_PORT)) 202 + return false; 203 + 204 + return true; 205 + } 206 + 169 207 static bool 170 208 conntrack_mt(const struct sk_buff *skb, const struct net_device *in, 171 209 const struct net_device *out, const struct xt_match *match, ··· 238 200 239 201 if (ct == NULL) 240 202 return info->match_flags & XT_CONNTRACK_STATE; 241 - 242 - if ((info->match_flags & XT_CONNTRACK_PROTO) && 243 - ((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum == 244 - info->l4proto) ^ !(info->invert_flags & XT_CONNTRACK_PROTO))) 203 + if ((info->match_flags & XT_CONNTRACK_DIRECTION) && 204 + (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) ^ 205 + !!(info->invert_flags & XT_CONNTRACK_DIRECTION)) 245 206 return false; 246 207 247 208 if (info->match_flags & XT_CONNTRACK_ORIGSRC) ··· 262 225 if (conntrack_mt_repldst(ct, info, match->family) ^ 263 226 !(info->invert_flags & XT_CONNTRACK_REPLDST)) 264 227 return false; 228 + 229 + if (!ct_proto_port_check(info, ct)) 230 + return false; 265 231 266 232 if ((info->match_flags & XT_CONNTRACK_STATUS) && 267 233 (!!(info->status_mask & ct->status) ^