mirror of
https://github.com/vishvananda/netlink
synced 2025-03-21 02:27:38 +00:00
RouteGetWithOptions: Add UID option
This commit is contained in:
parent
7e7feb220f
commit
6e2993d135
@ -1298,6 +1298,7 @@ type RouteGetOptions struct {
|
||||
Oif string
|
||||
VrfName string
|
||||
SrcAddr net.IP
|
||||
UID *uint32
|
||||
}
|
||||
|
||||
// RouteGetWithOptions gets a route to a specific destination from the host system.
|
||||
@ -1384,6 +1385,13 @@ func (h *Handle) RouteGetWithOptions(destination net.IP, options *RouteGetOption
|
||||
|
||||
req.AddData(nl.NewRtAttr(unix.RTA_SRC, srcAddr))
|
||||
}
|
||||
|
||||
if options.UID != nil {
|
||||
uid := *options.UID
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, uid)
|
||||
req.AddData(nl.NewRtAttr(unix.RTA_UID, b))
|
||||
}
|
||||
}
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWROUTE)
|
||||
|
@ -1644,3 +1644,99 @@ func TestRouteViaAddDel(t *testing.T) {
|
||||
t.Fatal("Route not removed properly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouteUIDOption(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
// setup eth0 so that network is reachable
|
||||
err := LinkAdd(&Dummy{LinkAttrs{Name: "eth0"}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
link, err := LinkByName("eth0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = LinkSetUp(link); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
addr := &Addr{
|
||||
IPNet: &net.IPNet{
|
||||
IP: net.IPv4(192, 168, 1, 1),
|
||||
Mask: net.CIDRMask(16, 32),
|
||||
},
|
||||
}
|
||||
if err = AddrAdd(link, addr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// a table different than unix.RT_TABLE_MAIN
|
||||
testtable := 1000
|
||||
|
||||
gw1 := net.IPv4(192, 168, 1, 254)
|
||||
gw2 := net.IPv4(192, 168, 2, 254)
|
||||
|
||||
// add default route via gw1 (in main route table by default)
|
||||
defaultRouteMain := Route{
|
||||
Dst: nil,
|
||||
Gw: gw1,
|
||||
}
|
||||
if err := RouteAdd(&defaultRouteMain); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// add default route via gw2 in test route table
|
||||
defaultRouteTest := Route{
|
||||
Dst: nil,
|
||||
Gw: gw2,
|
||||
Table: testtable,
|
||||
}
|
||||
if err := RouteAdd(&defaultRouteTest); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// check the routes are in different tables
|
||||
routes, err := RouteListFiltered(FAMILY_V4, &Route{
|
||||
Dst: nil,
|
||||
Table: unix.RT_TABLE_UNSPEC,
|
||||
}, RT_FILTER_DST|RT_FILTER_TABLE)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(routes) != 2 || routes[0].Table == routes[1].Table {
|
||||
t.Fatal("Routes not added properly")
|
||||
}
|
||||
|
||||
// add a rule that uidrange match should result in route lookup of test table for uid other than current
|
||||
// current uid is 0 due to skipUnlessRoot()
|
||||
var uid uint32 = 1000
|
||||
rule := NewRule()
|
||||
rule.UIDRange = NewRuleUIDRange(uid, uid)
|
||||
rule.Table = testtable
|
||||
if err := RuleAdd(rule); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dstIP := net.IPv4(10, 1, 1, 1)
|
||||
|
||||
// check getting route without UID option
|
||||
routes, err = RouteGetWithOptions(dstIP, &RouteGetOptions{UID: nil})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// current uid is outside uidrange; rule does not apply; lookup main table
|
||||
if len(routes) != 1 || !routes[0].Gw.Equal(gw1) {
|
||||
t.Fatal(routes)
|
||||
}
|
||||
|
||||
// check getting route with UID option
|
||||
routes, err = RouteGetWithOptions(dstIP, &RouteGetOptions{UID: &uid})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// option uid is within uidrange; rule applies; lookup test table
|
||||
if len(routes) != 1 || !routes[0].Gw.Equal(gw2) {
|
||||
t.Fatal(routes)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user