@@ -36,9 +36,10 @@ MODULE_ALIAS("ipt_connmark");
3636MODULE_ALIAS ("ip6t_connmark" );
3737
3838static unsigned int
39- connmark_tg (struct sk_buff * skb , const struct xt_action_param * par )
39+ connmark_tg_shift (struct sk_buff * skb ,
40+ const struct xt_connmark_tginfo1 * info ,
41+ u8 shift_bits , u8 shift_dir )
4042{
41- const struct xt_connmark_tginfo1 * info = par -> targinfo ;
4243 enum ip_conntrack_info ctinfo ;
4344 struct nf_conn * ct ;
4445 u_int32_t newmark ;
@@ -50,29 +51,57 @@ connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
5051 switch (info -> mode ) {
5152 case XT_CONNMARK_SET :
5253 newmark = (ct -> mark & ~info -> ctmask ) ^ info -> ctmark ;
54+ if (shift_dir == D_SHIFT_RIGHT )
55+ newmark >>= shift_bits ;
56+ else
57+ newmark <<= shift_bits ;
5358 if (ct -> mark != newmark ) {
5459 ct -> mark = newmark ;
5560 nf_conntrack_event_cache (IPCT_MARK , ct );
5661 }
5762 break ;
5863 case XT_CONNMARK_SAVE :
5964 newmark = (ct -> mark & ~info -> ctmask ) ^
60- (skb -> mark & info -> nfmask );
65+ (skb -> mark & info -> nfmask );
66+ if (shift_dir == D_SHIFT_RIGHT )
67+ newmark >>= shift_bits ;
68+ else
69+ newmark <<= shift_bits ;
6170 if (ct -> mark != newmark ) {
6271 ct -> mark = newmark ;
6372 nf_conntrack_event_cache (IPCT_MARK , ct );
6473 }
6574 break ;
6675 case XT_CONNMARK_RESTORE :
6776 newmark = (skb -> mark & ~info -> nfmask ) ^
68- (ct -> mark & info -> ctmask );
77+ (ct -> mark & info -> ctmask );
78+ if (shift_dir == D_SHIFT_RIGHT )
79+ newmark >>= shift_bits ;
80+ else
81+ newmark <<= shift_bits ;
6982 skb -> mark = newmark ;
7083 break ;
7184 }
72-
7385 return XT_CONTINUE ;
7486}
7587
88+ static unsigned int
89+ connmark_tg (struct sk_buff * skb , const struct xt_action_param * par )
90+ {
91+ const struct xt_connmark_tginfo1 * info = par -> targinfo ;
92+
93+ return connmark_tg_shift (skb , info , 0 , 0 );
94+ }
95+
96+ static unsigned int
97+ connmark_tg_v2 (struct sk_buff * skb , const struct xt_action_param * par )
98+ {
99+ const struct xt_connmark_tginfo2 * info = par -> targinfo ;
100+
101+ return connmark_tg_shift (skb , (const struct xt_connmark_tginfo1 * )info ,
102+ info -> shift_bits , info -> shift_dir );
103+ }
104+
76105static int connmark_tg_check (const struct xt_tgchk_param * par )
77106{
78107 int ret ;
@@ -119,15 +148,27 @@ static void connmark_mt_destroy(const struct xt_mtdtor_param *par)
119148 nf_ct_netns_put (par -> net , par -> family );
120149}
121150
122- static struct xt_target connmark_tg_reg __read_mostly = {
123- .name = "CONNMARK" ,
124- .revision = 1 ,
125- .family = NFPROTO_UNSPEC ,
126- .checkentry = connmark_tg_check ,
127- .target = connmark_tg ,
128- .targetsize = sizeof (struct xt_connmark_tginfo1 ),
129- .destroy = connmark_tg_destroy ,
130- .me = THIS_MODULE ,
151+ static struct xt_target connmark_tg_reg [] __read_mostly = {
152+ {
153+ .name = "CONNMARK" ,
154+ .revision = 1 ,
155+ .family = NFPROTO_UNSPEC ,
156+ .checkentry = connmark_tg_check ,
157+ .target = connmark_tg ,
158+ .targetsize = sizeof (struct xt_connmark_tginfo1 ),
159+ .destroy = connmark_tg_destroy ,
160+ .me = THIS_MODULE ,
161+ },
162+ {
163+ .name = "CONNMARK" ,
164+ .revision = 2 ,
165+ .family = NFPROTO_UNSPEC ,
166+ .checkentry = connmark_tg_check ,
167+ .target = connmark_tg_v2 ,
168+ .targetsize = sizeof (struct xt_connmark_tginfo2 ),
169+ .destroy = connmark_tg_destroy ,
170+ .me = THIS_MODULE ,
171+ }
131172};
132173
133174static struct xt_match connmark_mt_reg __read_mostly = {
@@ -145,12 +186,14 @@ static int __init connmark_mt_init(void)
145186{
146187 int ret ;
147188
148- ret = xt_register_target (& connmark_tg_reg );
189+ ret = xt_register_targets (connmark_tg_reg ,
190+ ARRAY_SIZE (connmark_tg_reg ));
149191 if (ret < 0 )
150192 return ret ;
151193 ret = xt_register_match (& connmark_mt_reg );
152194 if (ret < 0 ) {
153- xt_unregister_target (& connmark_tg_reg );
195+ xt_unregister_targets (connmark_tg_reg ,
196+ ARRAY_SIZE (connmark_tg_reg ));
154197 return ret ;
155198 }
156199 return 0 ;
@@ -159,7 +202,7 @@ static int __init connmark_mt_init(void)
159202static void __exit connmark_mt_exit (void )
160203{
161204 xt_unregister_match (& connmark_mt_reg );
162- xt_unregister_target (& connmark_tg_reg );
205+ xt_unregister_target (connmark_tg_reg );
163206}
164207
165208module_init (connmark_mt_init );
0 commit comments