localRoute constructs a local route from the netlink message.
(msg *nlmsg.Message)
| 951 | |
| 952 | // localRoute constructs a local route from the netlink message. |
| 953 | func (s *Stack) localRoute(msg *nlmsg.Message) (tcpip.Route, *syserr.Error) { |
| 954 | var rtMsg linux.RouteMessage |
| 955 | attrs, ok := msg.GetData(&rtMsg) |
| 956 | if !ok { |
| 957 | return tcpip.Route{}, syserr.ErrInvalidArgument |
| 958 | } |
| 959 | |
| 960 | route := inet.Route{ |
| 961 | Family: rtMsg.Family, |
| 962 | DstLen: rtMsg.DstLen, |
| 963 | SrcLen: rtMsg.SrcLen, |
| 964 | TOS: rtMsg.TOS, |
| 965 | Table: rtMsg.Table, |
| 966 | Protocol: rtMsg.Protocol, |
| 967 | Scope: rtMsg.Scope, |
| 968 | Type: rtMsg.Type, |
| 969 | Flags: rtMsg.Flags, |
| 970 | } |
| 971 | |
| 972 | for !attrs.Empty() { |
| 973 | ahdr, value, rest, ok := attrs.ParseFirst() |
| 974 | if !ok { |
| 975 | return tcpip.Route{}, syserr.ErrInvalidArgument |
| 976 | } |
| 977 | attrs = rest |
| 978 | |
| 979 | switch ahdr.Type { |
| 980 | case linux.RTA_DST: |
| 981 | if len(value) < 1 { |
| 982 | return tcpip.Route{}, syserr.ErrInvalidArgument |
| 983 | } |
| 984 | route.DstAddr = value |
| 985 | case linux.RTA_SRC: |
| 986 | if len(value) < 1 { |
| 987 | return tcpip.Route{}, syserr.ErrInvalidArgument |
| 988 | } |
| 989 | route.SrcAddr = value |
| 990 | case linux.RTA_OIF: |
| 991 | oif := nlmsg.BytesView(value) |
| 992 | outputInterface, ok := oif.Int32() |
| 993 | if !ok { |
| 994 | return tcpip.Route{}, syserr.ErrInvalidArgument |
| 995 | } |
| 996 | if _, exist := s.Interfaces()[outputInterface]; !exist { |
| 997 | return tcpip.Route{}, syserr.ErrNoDevice |
| 998 | } |
| 999 | route.OutputInterface = outputInterface |
| 1000 | case linux.RTA_GATEWAY: |
| 1001 | if len(value) < 1 { |
| 1002 | return tcpip.Route{}, syserr.ErrInvalidArgument |
| 1003 | } |
| 1004 | route.GatewayAddr = value |
| 1005 | case linux.RTA_PRIORITY: |
| 1006 | default: |
| 1007 | log.Warningf("Unknown attribute: %v", ahdr.Type) |
| 1008 | return tcpip.Route{}, syserr.ErrNotSupported |
| 1009 | } |
| 1010 | } |
no test coverage detected