Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
I
iproute2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
iproute2
Commits
e50e9f91
Commit
e50e9f91
authored
Dec 11, 2007
by
Stephen Hemminger
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into net-2.6.25
parents
7ca30b78
4b270b17
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
315 additions
and
17 deletions
+315
-17
doc/ip-cref.tex
doc/ip-cref.tex
+3
-10
include/linux/tc_act/tc_nat.h
include/linux/tc_act/tc_nat.h
+29
-0
lib/libnetlink.c
lib/libnetlink.c
+1
-1
lib/utils.c
lib/utils.c
+44
-1
tc/Makefile
tc/Makefile
+1
-0
tc/f_fw.c
tc/f_fw.c
+24
-5
tc/m_nat.c
tc/m_nat.c
+213
-0
No files found.
doc/ip-cref.tex
View file @
e50e9f91
...
...
@@ -298,9 +298,9 @@ Do not use it, if you do not understand what this operation really does.
\vskip
1
mm
\begin
{
NB
}
The
{
\tt
ip
}
utility does not change the
\verb
|PROMISC|
o
r
\verb
|ALLMULTI| flags. These flags are considered
obsolete and should not be changed administratively
.
The
\verb
|PROMISC| and
\verb
|ALLMULTI| flags are considered
o
bsolete and should not be changed administratively, though
the
{
\tt
ip
}
utility will allow that
.
\end
{
NB
}
\paragraph
{
Warning:
}
If multiple parameter changes are requested,
...
...
@@ -450,13 +450,6 @@ or not implemented (\verb|DEBUG|) or specific to some devices
(
\verb
|MASTER|,
\verb
|AUTOMEDIA| and
\verb
|PORTSEL|
)
. We do not discuss
them here.
\end
{
NB
}
\begin
{
NB
}
The values of
\verb
|PROMISC| and
\verb
|ALLMULTI| flags
shown by the
\verb
|ifconfig| utility and by the
\verb
|ip| utility
are
{
\em
different
\/
}
.
\verb
|ip link ls| shows the true device state,
while
\verb
|ifconfig| shows the virtual state which was set with
\verb
|ifconfig| itself.
\end
{
NB
}
The second line contains information on the link layer addresses
...
...
include/linux/tc_act/tc_nat.h
0 → 100644
View file @
e50e9f91
#ifndef __LINUX_TC_NAT_H
#define __LINUX_TC_NAT_H
#include <linux/pkt_cls.h>
#include <linux/types.h>
#define TCA_ACT_NAT 9
enum
{
TCA_NAT_UNSPEC
,
TCA_NAT_PARMS
,
TCA_NAT_TM
,
__TCA_NAT_MAX
};
#define TCA_NAT_MAX (__TCA_NAT_MAX - 1)
#define TCA_NAT_FLAG_EGRESS 1
struct
tc_nat
{
tc_gen
;
__be32
old_addr
;
__be32
new_addr
;
__be32
mask
;
__u32
flags
;
};
#endif
lib/libnetlink.c
View file @
e50e9f91
...
...
@@ -632,6 +632,6 @@ int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rt
rta
=
RTA_DATA
(
rta
)
+
RTA_ALIGN
(
len
);
return
parse_rtattr_nested
(
tb
,
max
,
rta
);
}
memset
(
tb
,
0
,
sizeof
(
struct
rtattr
*
)
*
max
);
memset
(
tb
,
0
,
sizeof
(
struct
rtattr
*
)
*
(
max
+
1
)
);
return
0
;
}
lib/utils.c
View file @
e50e9f91
...
...
@@ -47,6 +47,48 @@ int get_integer(int *val, const char *arg, int base)
return
0
;
}
/* a valid netmask must be 2^n - 1 */
static
int
is_valid_netmask
(
const
inet_prefix
*
addr
)
{
uint32_t
host
;
if
(
addr
->
family
!=
AF_INET
)
return
0
;
host
=
~
ntohl
(
addr
->
data
[
0
]);
return
(
host
&
(
host
+
1
))
==
0
;
}
static
unsigned
cidr
(
const
inet_prefix
*
addr
)
{
unsigned
bits
=
0
;
u_int32_t
mask
;
for
(
mask
=
ntohl
(
addr
->
data
[
0
]);
mask
;
mask
<<=
1
)
++
bits
;
return
bits
;
}
static
int
get_netmask
(
unsigned
*
val
,
const
char
*
arg
,
int
base
)
{
inet_prefix
addr
;
if
(
!
get_unsigned
(
val
,
arg
,
base
))
return
0
;
/* try coverting dotted quad to CIDR */
if
(
!
get_addr_1
(
&
addr
,
arg
,
AF_INET
))
{
if
(
is_valid_netmask
(
&
addr
))
return
0
;
*
val
=
cidr
(
&
addr
);
}
return
-
1
;
}
int
get_unsigned
(
unsigned
*
val
,
const
char
*
arg
,
int
base
)
{
unsigned
long
res
;
...
...
@@ -304,7 +346,8 @@ int get_prefix_1(inet_prefix *dst, char *arg, int family)
dst
->
bitlen
=
32
;
}
if
(
slash
)
{
if
(
get_unsigned
(
&
plen
,
slash
+
1
,
0
)
||
plen
>
dst
->
bitlen
)
{
if
(
get_netmask
(
&
plen
,
slash
+
1
,
0
)
||
plen
>
dst
->
bitlen
)
{
err
=
-
1
;
goto
done
;
}
...
...
tc/Makefile
View file @
e50e9f91
...
...
@@ -27,6 +27,7 @@ TCMODULES += q_htb.o
TCMODULES
+=
m_gact.o
TCMODULES
+=
m_mirred.o
TCMODULES
+=
m_ipt.o
TCMODULES
+=
m_nat.o
TCMODULES
+=
m_pedit.o
TCMODULES
+=
p_ip.o
TCMODULES
+=
p_icmp.o
...
...
tc/f_fw.c
View file @
e50e9f91
...
...
@@ -40,19 +40,30 @@ static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **a
memset
(
&
tp
,
0
,
sizeof
(
tp
));
tail
=
NLMSG_TAIL
(
n
);
addattr_l
(
n
,
4096
,
TCA_OPTIONS
,
NULL
,
0
);
if
(
handle
)
{
char
*
slash
;
__u32
mask
=
0
;
if
((
slash
=
strchr
(
handle
,
'/'
))
!=
NULL
)
*
slash
=
'\0'
;
if
(
get_u32
(
&
t
->
tcm_handle
,
handle
,
0
))
{
fprintf
(
stderr
,
"Illegal
\"
handle
\"\n
"
);
return
-
1
;
}
if
(
slash
)
{
if
(
get_u32
(
&
mask
,
slash
+
1
,
0
))
{
fprintf
(
stderr
,
"Illegal
\"
handle
\"
mask
\n
"
);
return
-
1
;
}
addattr32
(
n
,
MAX_MSG
,
TCA_FW_MASK
,
mask
);
}
}
if
(
argc
==
0
)
return
0
;
tail
=
NLMSG_TAIL
(
n
);
addattr_l
(
n
,
4096
,
TCA_OPTIONS
,
NULL
,
0
);
while
(
argc
>
0
)
{
if
(
matches
(
*
argv
,
"classid"
)
==
0
||
matches
(
*
argv
,
"flowid"
)
==
0
)
{
...
...
@@ -111,8 +122,16 @@ static int fw_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u
parse_rtattr_nested
(
tb
,
TCA_FW_MAX
,
opt
);
if
(
handle
)
fprintf
(
f
,
"handle 0x%x "
,
handle
);
if
(
handle
||
tb
[
TCA_FW_MASK
])
{
__u32
mark
=
0
,
mask
=
0
;
if
(
handle
)
mark
=
handle
;
if
(
tb
[
TCA_FW_MASK
]
&&
(
mask
=
*
(
__u32
*
)
RTA_DATA
(
tb
[
TCA_FW_MASK
]))
!=
0xFFFFFFFF
)
fprintf
(
f
,
"handle 0x%x/0x%x "
,
mark
,
mask
);
else
fprintf
(
f
,
"handle 0x%x "
,
handle
);
}
if
(
tb
[
TCA_FW_CLASSID
])
{
SPRINT_BUF
(
b1
);
...
...
tc/m_nat.c
0 → 100644
View file @
e50e9f91
/*
* m_nat.c NAT module
*
* This program is free software; you can distribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Herbert Xu <herbert@gondor.apana.org.au>
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <dlfcn.h>
#include "utils.h"
#include "tc_util.h"
#include <linux/tc_act/tc_nat.h>
static
void
explain
(
void
)
{
fprintf
(
stderr
,
"Usage: ... nat NAT
\n
"
"NAT := DIRECTION OLD NEW
\n
"
"DIRECTION := { ingress | egress }
\n
"
"OLD := PREFIX
\n
"
"NEW := ADDRESS
\n
"
);
}
static
void
usage
(
void
)
{
explain
();
exit
(
-
1
);
}
static
int
parse_nat_args
(
int
*
argc_p
,
char
***
argv_p
,
struct
tc_nat
*
sel
)
{
int
argc
=
*
argc_p
;
char
**
argv
=
*
argv_p
;
inet_prefix
addr
;
if
(
argc
<=
0
)
return
-
1
;
if
(
matches
(
*
argv
,
"egress"
)
==
0
)
sel
->
flags
|=
TCA_NAT_FLAG_EGRESS
;
else
if
(
matches
(
*
argv
,
"ingress"
)
!=
0
)
goto
bad_val
;
NEXT_ARG
();
if
(
get_prefix_1
(
&
addr
,
*
argv
,
AF_INET
))
goto
bad_val
;
sel
->
old_addr
=
addr
.
data
[
0
];
sel
->
mask
=
htonl
(
~
0u
<<
(
32
-
addr
.
bitlen
));
NEXT_ARG
();
if
(
get_prefix_1
(
&
addr
,
*
argv
,
AF_INET
))
goto
bad_val
;
sel
->
new_addr
=
addr
.
data
[
0
];
argc
--
;
argv
++
;
*
argc_p
=
argc
;
*
argv_p
=
argv
;
return
0
;
bad_val:
return
-
1
;
}
static
int
parse_nat
(
struct
action_util
*
a
,
int
*
argc_p
,
char
***
argv_p
,
int
tca_id
,
struct
nlmsghdr
*
n
)
{
struct
tc_nat
sel
;
int
argc
=
*
argc_p
;
char
**
argv
=
*
argv_p
;
int
ok
=
0
;
struct
rtattr
*
tail
;
memset
(
&
sel
,
0
,
sizeof
(
sel
));
while
(
argc
>
0
)
{
if
(
matches
(
*
argv
,
"nat"
)
==
0
)
{
NEXT_ARG
();
if
(
parse_nat_args
(
&
argc
,
&
argv
,
&
sel
))
{
fprintf
(
stderr
,
"Illegal nat construct (%s)
\n
"
,
*
argv
);
explain
();
return
-
1
;
}
ok
++
;
continue
;
}
else
if
(
matches
(
*
argv
,
"help"
)
==
0
)
{
usage
();
}
else
{
break
;
}
}
if
(
!
ok
)
{
explain
();
return
-
1
;
}
if
(
argc
)
{
if
(
matches
(
*
argv
,
"reclassify"
)
==
0
)
{
sel
.
action
=
TC_ACT_RECLASSIFY
;
argc
--
;
argv
++
;
}
else
if
(
matches
(
*
argv
,
"pipe"
)
==
0
)
{
sel
.
action
=
TC_ACT_PIPE
;
argc
--
;
argv
++
;
}
else
if
(
matches
(
*
argv
,
"drop"
)
==
0
||
matches
(
*
argv
,
"shot"
)
==
0
)
{
sel
.
action
=
TC_ACT_SHOT
;
argc
--
;
argv
++
;
}
else
if
(
matches
(
*
argv
,
"continue"
)
==
0
)
{
sel
.
action
=
TC_ACT_UNSPEC
;
argc
--
;
argv
++
;
}
else
if
(
matches
(
*
argv
,
"pass"
)
==
0
)
{
sel
.
action
=
TC_ACT_OK
;
argc
--
;
argv
++
;
}
}
if
(
argc
)
{
if
(
matches
(
*
argv
,
"index"
)
==
0
)
{
NEXT_ARG
();
if
(
get_u32
(
&
sel
.
index
,
*
argv
,
10
))
{
fprintf
(
stderr
,
"Pedit: Illegal
\"
index
\"\n
"
);
return
-
1
;
}
argc
--
;
argv
++
;
}
}
tail
=
NLMSG_TAIL
(
n
);
addattr_l
(
n
,
MAX_MSG
,
tca_id
,
NULL
,
0
);
addattr_l
(
n
,
MAX_MSG
,
TCA_NAT_PARMS
,
&
sel
,
sizeof
(
sel
));
tail
->
rta_len
=
(
char
*
)
NLMSG_TAIL
(
n
)
-
(
char
*
)
tail
;
*
argc_p
=
argc
;
*
argv_p
=
argv
;
return
0
;
}
static
int
print_nat
(
struct
action_util
*
au
,
FILE
*
f
,
struct
rtattr
*
arg
)
{
struct
tc_nat
*
sel
;
struct
rtattr
*
tb
[
TCA_NAT_MAX
+
1
];
char
buf1
[
256
];
char
buf2
[
256
];
SPRINT_BUF
(
buf3
);
int
len
;
if
(
arg
==
NULL
)
return
-
1
;
parse_rtattr_nested
(
tb
,
TCA_NAT_MAX
,
arg
);
if
(
tb
[
TCA_NAT_PARMS
]
==
NULL
)
{
fprintf
(
f
,
"[NULL nat parameters]"
);
return
-
1
;
}
sel
=
RTA_DATA
(
tb
[
TCA_NAT_PARMS
]);
len
=
ffs
(
sel
->
mask
);
len
=
len
?
33
-
len
:
0
;
fprintf
(
f
,
" nat %s %s/%d %s %s"
,
sel
->
flags
&
TCA_NAT_FLAG_EGRESS
?
"egress"
:
"ingress"
,
format_host
(
AF_INET
,
4
,
&
sel
->
old_addr
,
buf1
,
sizeof
(
buf1
)),
len
,
format_host
(
AF_INET
,
4
,
&
sel
->
new_addr
,
buf2
,
sizeof
(
buf2
)),
action_n2a
(
sel
->
action
,
buf3
,
sizeof
(
buf3
)));
if
(
show_stats
)
{
if
(
tb
[
TCA_NAT_TM
])
{
struct
tcf_t
*
tm
=
RTA_DATA
(
tb
[
TCA_NAT_TM
]);
print_tm
(
f
,
tm
);
}
}
return
0
;
}
struct
action_util
nat_action_util
=
{
.
id
=
"nat"
,
.
parse_aopt
=
parse_nat
,
.
print_aopt
=
print_nat
,
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment