func()

in cmd/core_plugin/network/route/route_linux.go [163:223]


func (lc *linuxClient) listRoutes(ctx context.Context, dev string, args []string) ([]Handle, error) {
	opts := run.Options{OutputType: run.OutputStdout, Name: "ip", Args: args}
	res, err := run.WithContext(ctx, opts)
	if err != nil {
		return nil, err
	}

	var routes []Handle
	for _, line := range strings.Split(res.Output, "\n") {
		line = strings.TrimSpace(line)

		if line == "" {
			continue
		}

		fields, err := parseRouteEntry(line)
		if err != nil {
			return nil, fmt.Errorf("failed to parse route entry: %w", err)
		}

		entry := Handle{
			Proto: fields["proto"],
			// InterfaceName will be overridden if the route entry has a dev field to
			// deal with interface aliases - the query may return a different name
			// than the one provided.
			InterfaceName: dev,
			Scope:         fields["scope"],
		}

		// Interface name is already set with the provided dev value but it's
		// worth overriding with the value from the route entry/table so we can deal
		// with interface aliases.
		if value, ok := fields["dev"]; ok {
			entry.InterfaceName = value
		}

		if value, ok := fields["destination"]; ok {
			dest, err := address.ParseIP(value)
			if err != nil {
				return nil, fmt.Errorf("failed to parse destination: %w", err)
			}
			entry.Destination = dest
		}

		if value, ok := fields["src"]; ok {
			source, err := address.ParseIP(value)
			if err != nil {
				return nil, fmt.Errorf("failed to parse source: %w", err)
			}
			entry.Source = source
		}

		if value, ok := fields["table"]; ok {
			entry.Table = value
		}

		routes = append(routes, entry)
	}

	return routes, nil
}