)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"38aa0bcf69ed0af11dc0d4d3f62e6903b2465f78","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"6405391d_1e1f4deb","updated":"2023-03-28 07:51:13.000000000","message":"The logic seems fine, but this really needs tests to confirm it. Please factor out the pure logic and test it.","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"}],"metropolis/node/core/network/main.go":[{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"38aa0bcf69ed0af11dc0d4d3f62e6903b2465f78","unresolved":true,"context_lines":[{"line_number":224,"context_line":"\t}"},{"line_number":225,"context_line":"\t// Choose between autoconfig and static config runnables"},{"line_number":226,"context_line":"\tif s.StaticConfig \u003d\u003d nil {"},{"line_number":227,"context_line":"\t\tsupervisor.Run(ctx, \"interfaces\", s.runInterfaces)"},{"line_number":228,"context_line":"\t} else {"},{"line_number":229,"context_line":"\t\tsupervisor.Run(ctx, \"static\", s.runStaticConfig)"},{"line_number":230,"context_line":"\t}"}],"source_content_type":"text/x-go","patch_set":4,"id":"c2e3bfae_5be838e9","line":227,"range":{"start_line":227,"start_character":23,"end_line":227,"end_character":33},"updated":"2023-03-28 07:51:13.000000000","message":"Rename this to \u0027dynamic\u0027 and \u0027runDynamicConfig\u0027.","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"b043a69dadeb7448954c91c2cffa57f3469af7a7","unresolved":false,"context_lines":[{"line_number":224,"context_line":"\t}"},{"line_number":225,"context_line":"\t// Choose between autoconfig and static config runnables"},{"line_number":226,"context_line":"\tif s.StaticConfig \u003d\u003d nil {"},{"line_number":227,"context_line":"\t\tsupervisor.Run(ctx, \"interfaces\", s.runInterfaces)"},{"line_number":228,"context_line":"\t} else {"},{"line_number":229,"context_line":"\t\tsupervisor.Run(ctx, \"static\", s.runStaticConfig)"},{"line_number":230,"context_line":"\t}"}],"source_content_type":"text/x-go","patch_set":4,"id":"56253ece_9132441c","line":227,"range":{"start_line":227,"start_character":23,"end_line":227,"end_character":33},"in_reply_to":"c2e3bfae_5be838e9","updated":"2023-03-30 14:42:44.000000000","message":"Done","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"}],"metropolis/node/core/network/static.go":[{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"38aa0bcf69ed0af11dc0d4d3f62e6903b2465f78","unresolved":true,"context_lines":[{"line_number":44,"context_line":"\tnetpb.Bond_LAYER3_4:       netlink.BOND_XMIT_HASH_POLICY_LAYER3_4,"},{"line_number":45,"context_line":"\tnetpb.Bond_ENCAP_LAYER2_3: netlink.BOND_XMIT_HASH_POLICY_ENCAP2_3,"},{"line_number":46,"context_line":"\tnetpb.Bond_ENCAP_LAYER3_4: netlink.BOND_XMIT_HASH_POLICY_ENCAP3_4,"},{"line_number":47,"context_line":"\tnetpb.Bond_VLAN_SRCMAC:    5, // TODO: constant not in netlink yet"},{"line_number":48,"context_line":"}"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"var validDevNameRegexp \u003d regexp.MustCompile(\"^[^/:[:space:]]{1,15}$\")"}],"source_content_type":"text/x-go","patch_set":4,"id":"548fb855_95cce93c","line":47,"range":{"start_line":47,"start_character":34,"end_line":47,"end_character":38},"updated":"2023-03-28 07:51:13.000000000","message":"TODO(tracking issue) or TODO(lorenz)","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"b043a69dadeb7448954c91c2cffa57f3469af7a7","unresolved":false,"context_lines":[{"line_number":44,"context_line":"\tnetpb.Bond_LAYER3_4:       netlink.BOND_XMIT_HASH_POLICY_LAYER3_4,"},{"line_number":45,"context_line":"\tnetpb.Bond_ENCAP_LAYER2_3: netlink.BOND_XMIT_HASH_POLICY_ENCAP2_3,"},{"line_number":46,"context_line":"\tnetpb.Bond_ENCAP_LAYER3_4: netlink.BOND_XMIT_HASH_POLICY_ENCAP3_4,"},{"line_number":47,"context_line":"\tnetpb.Bond_VLAN_SRCMAC:    5, // TODO: constant not in netlink yet"},{"line_number":48,"context_line":"}"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"var validDevNameRegexp \u003d regexp.MustCompile(\"^[^/:[:space:]]{1,15}$\")"}],"source_content_type":"text/x-go","patch_set":4,"id":"5bb46bf3_a10a5705","line":47,"range":{"start_line":47,"start_character":34,"end_line":47,"end_character":38},"in_reply_to":"548fb855_95cce93c","updated":"2023-03-30 14:42:44.000000000","message":"Done","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"38aa0bcf69ed0af11dc0d4d3f62e6903b2465f78","unresolved":true,"context_lines":[{"line_number":50,"context_line":"var validDevNameRegexp \u003d regexp.MustCompile(\"^[^/:[:space:]]{1,15}$\")"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"func isValidDevName(name string) error {"},{"line_number":53,"context_line":"\tif name \u003d\u003d \".\" || name \u003d\u003d \"..\" {"},{"line_number":54,"context_line":"\t\treturn errors.New(\"cannot be \\\".\\\" or \\\"..\\\"\")"},{"line_number":55,"context_line":"\t}"},{"line_number":56,"context_line":"\tif strings.ContainsRune(name, \u0027%\u0027) {"},{"line_number":57,"context_line":"\t\treturn errors.New(\"contains \\\"%\\\" sign which dynamically allocate names, this is disallowed\")"},{"line_number":58,"context_line":"\t}"}],"source_content_type":"text/x-go","patch_set":4,"id":"d27a618b_f2554353","line":55,"range":{"start_line":53,"start_character":1,"end_line":55,"end_character":2},"updated":"2023-03-28 07:51:13.000000000","message":"But an interface starting with a period is fine?","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"b043a69dadeb7448954c91c2cffa57f3469af7a7","unresolved":false,"context_lines":[{"line_number":50,"context_line":"var validDevNameRegexp \u003d regexp.MustCompile(\"^[^/:[:space:]]{1,15}$\")"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"func isValidDevName(name string) error {"},{"line_number":53,"context_line":"\tif name \u003d\u003d \".\" || name \u003d\u003d \"..\" {"},{"line_number":54,"context_line":"\t\treturn errors.New(\"cannot be \\\".\\\" or \\\"..\\\"\")"},{"line_number":55,"context_line":"\t}"},{"line_number":56,"context_line":"\tif strings.ContainsRune(name, \u0027%\u0027) {"},{"line_number":57,"context_line":"\t\treturn errors.New(\"contains \\\"%\\\" sign which dynamically allocate names, this is disallowed\")"},{"line_number":58,"context_line":"\t}"}],"source_content_type":"text/x-go","patch_set":4,"id":"b15ca1e1_36e228a0","line":55,"range":{"start_line":53,"start_character":1,"end_line":55,"end_character":2},"in_reply_to":"d27a618b_f2554353","updated":"2023-03-30 14:42:44.000000000","message":"Yes","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"38aa0bcf69ed0af11dc0d4d3f62e6903b2465f78","unresolved":true,"context_lines":[{"line_number":73,"context_line":"}"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"func (s *Service) runStaticConfig(ctx context.Context) error {"},{"line_number":76,"context_line":"\tvar depGraph toposort.Graph[string]"},{"line_number":77,"context_line":"\tifMap :\u003d make(map[string]*netpb.Interface)"},{"line_number":78,"context_line":"\tfor _, iface :\u003d range s.StaticConfig.Interface {"},{"line_number":79,"context_line":"\t\tif err :\u003d isValidDevName(iface.Name); err !\u003d nil {"},{"line_number":80,"context_line":"\t\t\treturn fmt.Errorf(\"invalid interface name %q: %w\", iface.Name, err)"},{"line_number":81,"context_line":"\t\t}"},{"line_number":82,"context_line":"\t\tifMap[iface.Name] \u003d iface"},{"line_number":83,"context_line":"\t\tdepGraph.AddNode(iface.Name)"},{"line_number":84,"context_line":"\t\tswitch it :\u003d iface.Type.(type) {"},{"line_number":85,"context_line":"\t\tcase *netpb.Interface_Bond:"},{"line_number":86,"context_line":"\t\t\tfor _, depIf :\u003d range it.Bond.MemberInterface {"},{"line_number":87,"context_line":"\t\t\t\t// Bond interfaces are set up with no children, their children"},{"line_number":88,"context_line":"\t\t\t\t// are then added when they are configured. Thus this needs a"},{"line_number":89,"context_line":"\t\t\t\t// reverse dependency."},{"line_number":90,"context_line":"\t\t\t\tdepGraph.AddEdge(depIf, iface.Name)"},{"line_number":91,"context_line":"\t\t\t}"},{"line_number":92,"context_line":"\t\tcase *netpb.Interface_Vlan:"},{"line_number":93,"context_line":"\t\t\tdepGraph.AddEdge(iface.Name, it.Vlan.Parent)"},{"line_number":94,"context_line":"\t\t}"},{"line_number":95,"context_line":"\t}"},{"line_number":96,"context_line":"\tinterfaceOrder, err :\u003d depGraph.TopologicalOrder()"},{"line_number":97,"context_line":"\tif err !\u003d nil {"},{"line_number":98,"context_line":"\t\treturn fmt.Errorf(\"unable to calculate interface setup order: %w\", err)"},{"line_number":99,"context_line":"\t}"},{"line_number":100,"context_line":"\tvar sortedInterfaces []*netpb.Interface"},{"line_number":101,"context_line":"\tfor _, ifname :\u003d range interfaceOrder {"},{"line_number":102,"context_line":"\t\tif _, ok :\u003d ifMap[ifname]; !ok {"},{"line_number":103,"context_line":"\t\t\treturn fmt.Errorf(\"reference to interface name %q which does not exist in the config\", ifname)"},{"line_number":104,"context_line":"\t\t}"},{"line_number":105,"context_line":"\t\tsortedInterfaces \u003d append(sortedInterfaces, ifMap[ifname])"},{"line_number":106,"context_line":"\t}"},{"line_number":107,"context_line":"\tnameLinkMap :\u003d make(map[string]netlink.Link)"},{"line_number":108,"context_line":"\tnameParentMap :\u003d make(map[string]string)"},{"line_number":109,"context_line":""}],"source_content_type":"text/x-go","patch_set":4,"id":"75dbd11e_2586482d","line":106,"range":{"start_line":76,"start_character":0,"end_line":106,"end_character":2},"updated":"2023-03-28 07:51:13.000000000","message":"The validation/parsing/sorting part should live somewhere in //go (or //net/go or something) as we\u0027re likely going to re-use this elsewhere, eg. metroctl (to let users figure out if their config is valid ahead of time).\n\nAlso this would benefit from some simple tests for simple vlan/bond scenarios.","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"b043a69dadeb7448954c91c2cffa57f3469af7a7","unresolved":true,"context_lines":[{"line_number":73,"context_line":"}"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"func (s *Service) runStaticConfig(ctx context.Context) error {"},{"line_number":76,"context_line":"\tvar depGraph toposort.Graph[string]"},{"line_number":77,"context_line":"\tifMap :\u003d make(map[string]*netpb.Interface)"},{"line_number":78,"context_line":"\tfor _, iface :\u003d range s.StaticConfig.Interface {"},{"line_number":79,"context_line":"\t\tif err :\u003d isValidDevName(iface.Name); err !\u003d nil {"},{"line_number":80,"context_line":"\t\t\treturn fmt.Errorf(\"invalid interface name %q: %w\", iface.Name, err)"},{"line_number":81,"context_line":"\t\t}"},{"line_number":82,"context_line":"\t\tifMap[iface.Name] \u003d iface"},{"line_number":83,"context_line":"\t\tdepGraph.AddNode(iface.Name)"},{"line_number":84,"context_line":"\t\tswitch it :\u003d iface.Type.(type) {"},{"line_number":85,"context_line":"\t\tcase *netpb.Interface_Bond:"},{"line_number":86,"context_line":"\t\t\tfor _, depIf :\u003d range it.Bond.MemberInterface {"},{"line_number":87,"context_line":"\t\t\t\t// Bond interfaces are set up with no children, their children"},{"line_number":88,"context_line":"\t\t\t\t// are then added when they are configured. Thus this needs a"},{"line_number":89,"context_line":"\t\t\t\t// reverse dependency."},{"line_number":90,"context_line":"\t\t\t\tdepGraph.AddEdge(depIf, iface.Name)"},{"line_number":91,"context_line":"\t\t\t}"},{"line_number":92,"context_line":"\t\tcase *netpb.Interface_Vlan:"},{"line_number":93,"context_line":"\t\t\tdepGraph.AddEdge(iface.Name, it.Vlan.Parent)"},{"line_number":94,"context_line":"\t\t}"},{"line_number":95,"context_line":"\t}"},{"line_number":96,"context_line":"\tinterfaceOrder, err :\u003d depGraph.TopologicalOrder()"},{"line_number":97,"context_line":"\tif err !\u003d nil {"},{"line_number":98,"context_line":"\t\treturn fmt.Errorf(\"unable to calculate interface setup order: %w\", err)"},{"line_number":99,"context_line":"\t}"},{"line_number":100,"context_line":"\tvar sortedInterfaces []*netpb.Interface"},{"line_number":101,"context_line":"\tfor _, ifname :\u003d range interfaceOrder {"},{"line_number":102,"context_line":"\t\tif _, ok :\u003d ifMap[ifname]; !ok {"},{"line_number":103,"context_line":"\t\t\treturn fmt.Errorf(\"reference to interface name %q which does not exist in the config\", ifname)"},{"line_number":104,"context_line":"\t\t}"},{"line_number":105,"context_line":"\t\tsortedInterfaces \u003d append(sortedInterfaces, ifMap[ifname])"},{"line_number":106,"context_line":"\t}"},{"line_number":107,"context_line":"\tnameLinkMap :\u003d make(map[string]netlink.Link)"},{"line_number":108,"context_line":"\tnameParentMap :\u003d make(map[string]string)"},{"line_number":109,"context_line":""}],"source_content_type":"text/x-go","patch_set":4,"id":"a2d7178d_e4704cb8","line":106,"range":{"start_line":76,"start_character":0,"end_line":106,"end_character":2},"in_reply_to":"75dbd11e_2586482d","updated":"2023-03-30 14:42:44.000000000","message":"I thought about this and while this is true, I\u0027m not sure how to split this out. Validating a config is a lot more work than just what\u0027s done here. Maybe this is better left for later and a dedicated validator in //go/net.","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"9e126a446f508724e5f03b51a3cedff292d367df","unresolved":false,"context_lines":[{"line_number":73,"context_line":"}"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"func (s *Service) runStaticConfig(ctx context.Context) error {"},{"line_number":76,"context_line":"\tvar depGraph toposort.Graph[string]"},{"line_number":77,"context_line":"\tifMap :\u003d make(map[string]*netpb.Interface)"},{"line_number":78,"context_line":"\tfor _, iface :\u003d range s.StaticConfig.Interface {"},{"line_number":79,"context_line":"\t\tif err :\u003d isValidDevName(iface.Name); err !\u003d nil {"},{"line_number":80,"context_line":"\t\t\treturn fmt.Errorf(\"invalid interface name %q: %w\", iface.Name, err)"},{"line_number":81,"context_line":"\t\t}"},{"line_number":82,"context_line":"\t\tifMap[iface.Name] \u003d iface"},{"line_number":83,"context_line":"\t\tdepGraph.AddNode(iface.Name)"},{"line_number":84,"context_line":"\t\tswitch it :\u003d iface.Type.(type) {"},{"line_number":85,"context_line":"\t\tcase *netpb.Interface_Bond:"},{"line_number":86,"context_line":"\t\t\tfor _, depIf :\u003d range it.Bond.MemberInterface {"},{"line_number":87,"context_line":"\t\t\t\t// Bond interfaces are set up with no children, their children"},{"line_number":88,"context_line":"\t\t\t\t// are then added when they are configured. Thus this needs a"},{"line_number":89,"context_line":"\t\t\t\t// reverse dependency."},{"line_number":90,"context_line":"\t\t\t\tdepGraph.AddEdge(depIf, iface.Name)"},{"line_number":91,"context_line":"\t\t\t}"},{"line_number":92,"context_line":"\t\tcase *netpb.Interface_Vlan:"},{"line_number":93,"context_line":"\t\t\tdepGraph.AddEdge(iface.Name, it.Vlan.Parent)"},{"line_number":94,"context_line":"\t\t}"},{"line_number":95,"context_line":"\t}"},{"line_number":96,"context_line":"\tinterfaceOrder, err :\u003d depGraph.TopologicalOrder()"},{"line_number":97,"context_line":"\tif err !\u003d nil {"},{"line_number":98,"context_line":"\t\treturn fmt.Errorf(\"unable to calculate interface setup order: %w\", err)"},{"line_number":99,"context_line":"\t}"},{"line_number":100,"context_line":"\tvar sortedInterfaces []*netpb.Interface"},{"line_number":101,"context_line":"\tfor _, ifname :\u003d range interfaceOrder {"},{"line_number":102,"context_line":"\t\tif _, ok :\u003d ifMap[ifname]; !ok {"},{"line_number":103,"context_line":"\t\t\treturn fmt.Errorf(\"reference to interface name %q which does not exist in the config\", ifname)"},{"line_number":104,"context_line":"\t\t}"},{"line_number":105,"context_line":"\t\tsortedInterfaces \u003d append(sortedInterfaces, ifMap[ifname])"},{"line_number":106,"context_line":"\t}"},{"line_number":107,"context_line":"\tnameLinkMap :\u003d make(map[string]netlink.Link)"},{"line_number":108,"context_line":"\tnameParentMap :\u003d make(map[string]string)"},{"line_number":109,"context_line":""}],"source_content_type":"text/x-go","patch_set":4,"id":"da1ab47f_a503292a","line":106,"range":{"start_line":76,"start_character":0,"end_line":106,"end_character":2},"in_reply_to":"a2d7178d_e4704cb8","updated":"2023-03-30 15:15:45.000000000","message":"Ack","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"38aa0bcf69ed0af11dc0d4d3f62e6903b2465f78","unresolved":true,"context_lines":[{"line_number":107,"context_line":"\tnameLinkMap :\u003d make(map[string]netlink.Link)"},{"line_number":108,"context_line":"\tnameParentMap :\u003d make(map[string]string)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"\t// List existing links"},{"line_number":111,"context_line":"\tlinks, err :\u003d netlink.LinkList()"},{"line_number":112,"context_line":"\tif err !\u003d nil {"},{"line_number":113,"context_line":"\t\treturn fmt.Errorf(\"failed to list network links: %w\", err)"}],"source_content_type":"text/x-go","patch_set":4,"id":"58295669_756d0e5b","line":110,"updated":"2023-03-28 07:51:13.000000000","message":"Factor all of this out into an separate function `func applyStaticConfig(sortedInterfaces []*netpb.Interface)`","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"b043a69dadeb7448954c91c2cffa57f3469af7a7","unresolved":true,"context_lines":[{"line_number":107,"context_line":"\tnameLinkMap :\u003d make(map[string]netlink.Link)"},{"line_number":108,"context_line":"\tnameParentMap :\u003d make(map[string]string)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"\t// List existing links"},{"line_number":111,"context_line":"\tlinks, err :\u003d netlink.LinkList()"},{"line_number":112,"context_line":"\tif err !\u003d nil {"},{"line_number":113,"context_line":"\t\treturn fmt.Errorf(\"failed to list network links: %w\", err)"}],"source_content_type":"text/x-go","patch_set":4,"id":"d73f22a5_a7ced408","line":110,"in_reply_to":"58295669_756d0e5b","updated":"2023-03-30 14:42:44.000000000","message":"There isn\u0027t much left in this function other than this after the refactoring.","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"9e126a446f508724e5f03b51a3cedff292d367df","unresolved":false,"context_lines":[{"line_number":107,"context_line":"\tnameLinkMap :\u003d make(map[string]netlink.Link)"},{"line_number":108,"context_line":"\tnameParentMap :\u003d make(map[string]string)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"\t// List existing links"},{"line_number":111,"context_line":"\tlinks, err :\u003d netlink.LinkList()"},{"line_number":112,"context_line":"\tif err !\u003d nil {"},{"line_number":113,"context_line":"\t\treturn fmt.Errorf(\"failed to list network links: %w\", err)"}],"source_content_type":"text/x-go","patch_set":4,"id":"889cfa02_0ddd98ab","line":110,"in_reply_to":"d73f22a5_a7ced408","updated":"2023-03-30 15:15:45.000000000","message":"Ack","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"38aa0bcf69ed0af11dc0d4d3f62e6903b2465f78","unresolved":true,"context_lines":[{"line_number":132,"context_line":""},{"line_number":133,"context_line":"\tfor _, i :\u003d range sortedInterfaces {"},{"line_number":134,"context_line":"\t\tvar newLink netlink.Link"},{"line_number":135,"context_line":"\t\tswitch it :\u003d i.Type.(type) {"},{"line_number":136,"context_line":"\t\tcase *netpb.Interface_Device:"},{"line_number":137,"context_line":"\t\t\tvar matchedDevices []*netlink.Device"},{"line_number":138,"context_line":"\t\t\tparsedHWAddr, err :\u003d net.ParseMAC(it.Device.HardwareAddress)"}],"source_content_type":"text/x-go","patch_set":4,"id":"610d04a2_8df67767","line":135,"range":{"start_line":135,"start_character":2,"end_line":135,"end_character":30},"updated":"2023-03-28 07:51:13.000000000","message":"Each one of the separate type handlers should be factor out to a separate function and would benefit from some simple tests.","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"b043a69dadeb7448954c91c2cffa57f3469af7a7","unresolved":false,"context_lines":[{"line_number":132,"context_line":""},{"line_number":133,"context_line":"\tfor _, i :\u003d range sortedInterfaces {"},{"line_number":134,"context_line":"\t\tvar newLink netlink.Link"},{"line_number":135,"context_line":"\t\tswitch it :\u003d i.Type.(type) {"},{"line_number":136,"context_line":"\t\tcase *netpb.Interface_Device:"},{"line_number":137,"context_line":"\t\t\tvar matchedDevices []*netlink.Device"},{"line_number":138,"context_line":"\t\t\tparsedHWAddr, err :\u003d net.ParseMAC(it.Device.HardwareAddress)"}],"source_content_type":"text/x-go","patch_set":4,"id":"1d3ad0ab_edd88027","line":135,"range":{"start_line":135,"start_character":2,"end_line":135,"end_character":30},"in_reply_to":"610d04a2_8df67767","updated":"2023-03-30 14:42:44.000000000","message":"Done","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"38aa0bcf69ed0af11dc0d4d3f62e6903b2465f78","unresolved":true,"context_lines":[{"line_number":263,"context_line":"\t\t\t\taddr.Flags |\u003d unix.IFA_F_NOPREFIXROUTE"},{"line_number":264,"context_line":"\t\t\t}"},{"line_number":265,"context_line":"\t\t\taddr.Flags |\u003d unix.IFA_F_PERMANENT"},{"line_number":266,"context_line":"\t\t\tif err :\u003d netlink.AddrAdd(newLink, \u0026addr); err !\u003d nil {"},{"line_number":267,"context_line":"\t\t\t\treturn fmt.Errorf(\"unable to add address %q to link %q: %w\", a, i.Name, err)"},{"line_number":268,"context_line":"\t\t\t}"},{"line_number":269,"context_line":"\t\t}"}],"source_content_type":"text/x-go","patch_set":4,"id":"3f967a1c_25eddb54","line":266,"range":{"start_line":266,"start_character":3,"end_line":266,"end_character":58},"updated":"2023-03-28 07:51:13.000000000","message":"Factor out everything up until AddrAdd and test.","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"b043a69dadeb7448954c91c2cffa57f3469af7a7","unresolved":false,"context_lines":[{"line_number":263,"context_line":"\t\t\t\taddr.Flags |\u003d unix.IFA_F_NOPREFIXROUTE"},{"line_number":264,"context_line":"\t\t\t}"},{"line_number":265,"context_line":"\t\t\taddr.Flags |\u003d unix.IFA_F_PERMANENT"},{"line_number":266,"context_line":"\t\t\tif err :\u003d netlink.AddrAdd(newLink, \u0026addr); err !\u003d nil {"},{"line_number":267,"context_line":"\t\t\t\treturn fmt.Errorf(\"unable to add address %q to link %q: %w\", a, i.Name, err)"},{"line_number":268,"context_line":"\t\t\t}"},{"line_number":269,"context_line":"\t\t}"}],"source_content_type":"text/x-go","patch_set":4,"id":"7073f5bb_6d42f782","line":266,"range":{"start_line":266,"start_character":3,"end_line":266,"end_character":58},"in_reply_to":"3f967a1c_25eddb54","updated":"2023-03-30 14:42:44.000000000","message":"Done","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"38aa0bcf69ed0af11dc0d4d3f62e6903b2465f78","unresolved":true,"context_lines":[{"line_number":304,"context_line":"\t\t\t\t// it is always treated as on-link."},{"line_number":305,"context_line":"\t\t\t\troute.Flags |\u003d int(netlink.FLAG_ONLINK)"},{"line_number":306,"context_line":"\t\t\t}"},{"line_number":307,"context_line":"\t\t\tif err :\u003d netlink.RouteAdd(\u0026route); err !\u003d nil {"},{"line_number":308,"context_line":"\t\t\t\treturn fmt.Errorf(\"failed adding route to %q for interface %q: %w\", r.Destination, i.Name, err)"},{"line_number":309,"context_line":"\t\t\t}"},{"line_number":310,"context_line":"\t\t}"}],"source_content_type":"text/x-go","patch_set":4,"id":"62a8de6a_bd552032","line":307,"range":{"start_line":307,"start_character":3,"end_line":307,"end_character":51},"updated":"2023-03-28 07:51:13.000000000","message":"Factor out everything up until RouteAdd and test.","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"b043a69dadeb7448954c91c2cffa57f3469af7a7","unresolved":false,"context_lines":[{"line_number":304,"context_line":"\t\t\t\t// it is always treated as on-link."},{"line_number":305,"context_line":"\t\t\t\troute.Flags |\u003d int(netlink.FLAG_ONLINK)"},{"line_number":306,"context_line":"\t\t\t}"},{"line_number":307,"context_line":"\t\t\tif err :\u003d netlink.RouteAdd(\u0026route); err !\u003d nil {"},{"line_number":308,"context_line":"\t\t\t\treturn fmt.Errorf(\"failed adding route to %q for interface %q: %w\", r.Destination, i.Name, err)"},{"line_number":309,"context_line":"\t\t\t}"},{"line_number":310,"context_line":"\t\t}"}],"source_content_type":"text/x-go","patch_set":4,"id":"9aaa7603_44388f7e","line":307,"range":{"start_line":307,"start_character":3,"end_line":307,"end_character":51},"in_reply_to":"62a8de6a_bd552032","updated":"2023-03-30 14:42:44.000000000","message":"Done","commit_id":"98f9fe677332b00d15299498cf932e2a288ad3fa"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"9e126a446f508724e5f03b51a3cedff292d367df","unresolved":true,"context_lines":[{"line_number":127,"context_line":"}"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"// getSortedIfaces returns a list of all interfaces to be configured in"},{"line_number":130,"context_line":"// an order which is valid to to configured them in, ie. parent interfaces"},{"line_number":131,"context_line":"// get configured before child interfaces. It also validates that all interfaces"},{"line_number":132,"context_line":"// referenced do in fact exist in the configuration."},{"line_number":133,"context_line":"func getSortedIfaces(s *Service) ([]*netpb.Interface, error) {"}],"source_content_type":"text/x-go","patch_set":6,"id":"6512a29b_f69ddbf8","line":130,"range":{"start_line":130,"start_character":21,"end_line":130,"end_character":51},"updated":"2023-03-30 15:15:45.000000000","message":"```suggestion\n// an order which is valid to configure them in, ie. parent interfaces\n```","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"d2203e4d92506b305790a40cc1ceeb7fcc649d92","unresolved":false,"context_lines":[{"line_number":127,"context_line":"}"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"// getSortedIfaces returns a list of all interfaces to be configured in"},{"line_number":130,"context_line":"// an order which is valid to to configured them in, ie. parent interfaces"},{"line_number":131,"context_line":"// get configured before child interfaces. It also validates that all interfaces"},{"line_number":132,"context_line":"// referenced do in fact exist in the configuration."},{"line_number":133,"context_line":"func getSortedIfaces(s *Service) ([]*netpb.Interface, error) {"}],"source_content_type":"text/x-go","patch_set":6,"id":"50099cf4_5ed9d4b4","line":130,"range":{"start_line":130,"start_character":21,"end_line":130,"end_character":51},"in_reply_to":"6512a29b_f69ddbf8","updated":"2023-03-30 16:05:42.000000000","message":"Done","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"9e126a446f508724e5f03b51a3cedff292d367df","unresolved":true,"context_lines":[{"line_number":158,"context_line":"\tvar sortedInterfaces []*netpb.Interface"},{"line_number":159,"context_line":"\tfor _, ifname :\u003d range interfaceOrder {"},{"line_number":160,"context_line":"\t\tif _, ok :\u003d ifMap[ifname]; !ok {"},{"line_number":161,"context_line":"\t\t\treturn nil, fmt.Errorf(\"reference to interface name %q which does not exist in the config\", ifname)"},{"line_number":162,"context_line":"\t\t}"},{"line_number":163,"context_line":"\t\tsortedInterfaces \u003d append(sortedInterfaces, ifMap[ifname])"},{"line_number":164,"context_line":"\t}"}],"source_content_type":"text/x-go","patch_set":6,"id":"57d6199d_ac38a395","line":161,"range":{"start_line":161,"start_character":27,"end_line":161,"end_character":36},"updated":"2023-03-30 15:15:45.000000000","message":"This sould say which interface holds that invalid reference. E.g. build a map of referee-\u003e[]referrer when adding the edges above, and quote them here.","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"d2203e4d92506b305790a40cc1ceeb7fcc649d92","unresolved":true,"context_lines":[{"line_number":158,"context_line":"\tvar sortedInterfaces []*netpb.Interface"},{"line_number":159,"context_line":"\tfor _, ifname :\u003d range interfaceOrder {"},{"line_number":160,"context_line":"\t\tif _, ok :\u003d ifMap[ifname]; !ok {"},{"line_number":161,"context_line":"\t\t\treturn nil, fmt.Errorf(\"reference to interface name %q which does not exist in the config\", ifname)"},{"line_number":162,"context_line":"\t\t}"},{"line_number":163,"context_line":"\t\tsortedInterfaces \u003d append(sortedInterfaces, ifMap[ifname])"},{"line_number":164,"context_line":"\t}"}],"source_content_type":"text/x-go","patch_set":6,"id":"809f989e_a237f17e","line":161,"range":{"start_line":161,"start_character":27,"end_line":161,"end_character":36},"in_reply_to":"57d6199d_ac38a395","updated":"2023-03-30 16:05:42.000000000","message":"I\u0027m going to push that into the toposort library. Seems like a super common thing to want for a dependency resolver. I removed the check here.","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"85db2c880c51e0f55b3ae3baa8f94eede5bf38b3","unresolved":true,"context_lines":[{"line_number":158,"context_line":"\tvar sortedInterfaces []*netpb.Interface"},{"line_number":159,"context_line":"\tfor _, ifname :\u003d range interfaceOrder {"},{"line_number":160,"context_line":"\t\tif _, ok :\u003d ifMap[ifname]; !ok {"},{"line_number":161,"context_line":"\t\t\treturn nil, fmt.Errorf(\"reference to interface name %q which does not exist in the config\", ifname)"},{"line_number":162,"context_line":"\t\t}"},{"line_number":163,"context_line":"\t\tsortedInterfaces \u003d append(sortedInterfaces, ifMap[ifname])"},{"line_number":164,"context_line":"\t}"}],"source_content_type":"text/x-go","patch_set":6,"id":"c4fd618c_8d1a3153","line":161,"range":{"start_line":161,"start_character":27,"end_line":161,"end_character":36},"in_reply_to":"809f989e_a237f17e","updated":"2023-03-30 16:28:39.000000000","message":"Alright, bump this back into my queue once it\u0027s rebased on top of the toposort functionality, or when that has been otherwise merged.","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"8aca8deee79d3dff6d8f3a67cf16273ee2c44699","unresolved":false,"context_lines":[{"line_number":158,"context_line":"\tvar sortedInterfaces []*netpb.Interface"},{"line_number":159,"context_line":"\tfor _, ifname :\u003d range interfaceOrder {"},{"line_number":160,"context_line":"\t\tif _, ok :\u003d ifMap[ifname]; !ok {"},{"line_number":161,"context_line":"\t\t\treturn nil, fmt.Errorf(\"reference to interface name %q which does not exist in the config\", ifname)"},{"line_number":162,"context_line":"\t\t}"},{"line_number":163,"context_line":"\t\tsortedInterfaces \u003d append(sortedInterfaces, ifMap[ifname])"},{"line_number":164,"context_line":"\t}"}],"source_content_type":"text/x-go","patch_set":6,"id":"c318965a_76c49d17","line":161,"range":{"start_line":161,"start_character":27,"end_line":161,"end_character":36},"in_reply_to":"c4fd618c_8d1a3153","updated":"2023-04-06 13:36:43.000000000","message":"Done","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"9e126a446f508724e5f03b51a3cedff292d367df","unresolved":true,"context_lines":[{"line_number":218,"context_line":"\t\t\t// otherwise the standard hardware address must match"},{"line_number":219,"context_line":"\t\t\tif len(d.dev.PermHardwareAddr) \u003e 0 {"},{"line_number":220,"context_line":"\t\t\t\tif !bytes.Equal(d.dev.PermHardwareAddr, parsedHWAddr) {"},{"line_number":221,"context_line":"\t\t\t\t\tfmt.Printf(\"mismatch perm %q: %s %s\\n\", d.dev.Name, d.dev.PermHardwareAddr, parsedHWAddr)"},{"line_number":222,"context_line":"\t\t\t\t\tcontinue"},{"line_number":223,"context_line":"\t\t\t\t}"},{"line_number":224,"context_line":"\t\t\t} else if !bytes.Equal(d.dev.HardwareAddr, parsedHWAddr) {"}],"source_content_type":"text/x-go","patch_set":6,"id":"cdf805d1_58c0c240","line":221,"range":{"start_line":221,"start_character":6,"end_line":221,"end_character":15},"updated":"2023-03-30 15:15:45.000000000","message":"Do not log to stdout like this (also elsewhere).","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"d2203e4d92506b305790a40cc1ceeb7fcc649d92","unresolved":false,"context_lines":[{"line_number":218,"context_line":"\t\t\t// otherwise the standard hardware address must match"},{"line_number":219,"context_line":"\t\t\tif len(d.dev.PermHardwareAddr) \u003e 0 {"},{"line_number":220,"context_line":"\t\t\t\tif !bytes.Equal(d.dev.PermHardwareAddr, parsedHWAddr) {"},{"line_number":221,"context_line":"\t\t\t\t\tfmt.Printf(\"mismatch perm %q: %s %s\\n\", d.dev.Name, d.dev.PermHardwareAddr, parsedHWAddr)"},{"line_number":222,"context_line":"\t\t\t\t\tcontinue"},{"line_number":223,"context_line":"\t\t\t\t}"},{"line_number":224,"context_line":"\t\t\t} else if !bytes.Equal(d.dev.HardwareAddr, parsedHWAddr) {"}],"source_content_type":"text/x-go","patch_set":6,"id":"9b6284dc_1c580315","line":221,"range":{"start_line":221,"start_character":6,"end_line":221,"end_character":15},"in_reply_to":"cdf805d1_58c0c240","updated":"2023-03-30 16:05:42.000000000","message":"Done","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"9e126a446f508724e5f03b51a3cedff292d367df","unresolved":true,"context_lines":[{"line_number":235,"context_line":"\t\tmatchedDevices \u003d append(matchedDevices, d.dev)"},{"line_number":236,"context_line":"\t}"},{"line_number":237,"context_line":"\tif len(matchedDevices) \u003c\u003d int(it.Device.Index) || it.Device.Index \u003c 0 {"},{"line_number":238,"context_line":"\t\treturn nil, fmt.Errorf(\"unable to satisfy match: %d %d\", len(matchedDevices), it.Device.Index)"},{"line_number":239,"context_line":"\t}"},{"line_number":240,"context_line":"\tdev :\u003d \u0026netlink.Device{"},{"line_number":241,"context_line":"\t\tLinkAttrs: netlink.NewLinkAttrs(),"}],"source_content_type":"text/x-go","patch_set":6,"id":"4ef97336_f98f408e","line":238,"range":{"start_line":238,"start_character":51,"end_line":238,"end_character":56},"updated":"2023-03-30 15:15:45.000000000","message":"This should be explained better.","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"d2203e4d92506b305790a40cc1ceeb7fcc649d92","unresolved":false,"context_lines":[{"line_number":235,"context_line":"\t\tmatchedDevices \u003d append(matchedDevices, d.dev)"},{"line_number":236,"context_line":"\t}"},{"line_number":237,"context_line":"\tif len(matchedDevices) \u003c\u003d int(it.Device.Index) || it.Device.Index \u003c 0 {"},{"line_number":238,"context_line":"\t\treturn nil, fmt.Errorf(\"unable to satisfy match: %d %d\", len(matchedDevices), it.Device.Index)"},{"line_number":239,"context_line":"\t}"},{"line_number":240,"context_line":"\tdev :\u003d \u0026netlink.Device{"},{"line_number":241,"context_line":"\t\tLinkAttrs: netlink.NewLinkAttrs(),"}],"source_content_type":"text/x-go","patch_set":6,"id":"1afc623b_b2ca0bfd","line":238,"range":{"start_line":238,"start_character":51,"end_line":238,"end_character":56},"in_reply_to":"4ef97336_f98f408e","updated":"2023-03-30 16:05:42.000000000","message":"Done","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"9e126a446f508724e5f03b51a3cedff292d367df","unresolved":true,"context_lines":[{"line_number":289,"context_line":"\t\t}"},{"line_number":290,"context_line":"\tcase *netpb.Bond_ActiveBackup_:"},{"line_number":291,"context_line":"\t\tnewBond.Mode \u003d netlink.BOND_MODE_ACTIVE_BACKUP"},{"line_number":292,"context_line":"\t}"},{"line_number":293,"context_line":"\treturn newBond, nil"},{"line_number":294,"context_line":"}"},{"line_number":295,"context_line":""}],"source_content_type":"text/x-go","patch_set":6,"id":"63f964f5_9583b7da","line":292,"range":{"start_line":292,"start_character":1,"end_line":292,"end_character":2},"updated":"2023-03-30 15:15:45.000000000","message":"default should probably return an error","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"d2203e4d92506b305790a40cc1ceeb7fcc649d92","unresolved":false,"context_lines":[{"line_number":289,"context_line":"\t\t}"},{"line_number":290,"context_line":"\tcase *netpb.Bond_ActiveBackup_:"},{"line_number":291,"context_line":"\t\tnewBond.Mode \u003d netlink.BOND_MODE_ACTIVE_BACKUP"},{"line_number":292,"context_line":"\t}"},{"line_number":293,"context_line":"\treturn newBond, nil"},{"line_number":294,"context_line":"}"},{"line_number":295,"context_line":""}],"source_content_type":"text/x-go","patch_set":6,"id":"42fb0b3c_3227dcf0","line":292,"range":{"start_line":292,"start_character":1,"end_line":292,"end_character":2},"in_reply_to":"63f964f5_9583b7da","updated":"2023-03-30 16:05:42.000000000","message":"Done","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"9e126a446f508724e5f03b51a3cedff292d367df","unresolved":true,"context_lines":[{"line_number":323,"context_line":""},{"line_number":324,"context_line":"func routeFromSpec(r *netpb.Interface_Route, link netlink.Link) error {"},{"line_number":325,"context_line":"\tvar route netlink.Route"},{"line_number":326,"context_line":"\tif strings.ContainsRune(r.Destination, \u0027/\u0027) {"},{"line_number":327,"context_line":"\t\t_, dstPrefix, err :\u003d net.ParseCIDR(r.Destination)"},{"line_number":328,"context_line":"\t\tif err !\u003d nil {"},{"line_number":329,"context_line":"\t\t\treturn fmt.Errorf(\"failed parsing %q as CIDR: %w\", r.Destination, err)"},{"line_number":330,"context_line":"\t\t}"},{"line_number":331,"context_line":"\t\troute.Dst \u003d dstPrefix"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"\t} else {"},{"line_number":334,"context_line":"\t\tdstIP :\u003d net.ParseIP(r.Destination)"},{"line_number":335,"context_line":"\t\tif dstIP \u003d\u003d nil {"},{"line_number":336,"context_line":"\t\t\treturn fmt.Errorf(\"failed parsing %q as IP\", r.Destination)"},{"line_number":337,"context_line":"\t\t}"},{"line_number":338,"context_line":"\t\troute.Dst.IP \u003d dstIP"},{"line_number":339,"context_line":"\t\troute.Dst.Mask \u003d singleHostMask(dstIP)"},{"line_number":340,"context_line":"\t}"},{"line_number":341,"context_line":"\troute.Protocol \u003d unix.RTPROT_STATIC"},{"line_number":342,"context_line":"\troute.LinkIndex \u003d link.Attrs().Index"},{"line_number":343,"context_line":"\troute.Priority \u003d int(r.Metric)"}],"source_content_type":"text/x-go","patch_set":6,"id":"f89b5a92_29b38250","line":340,"range":{"start_line":326,"start_character":1,"end_line":340,"end_character":2},"updated":"2023-03-30 15:15:45.000000000","message":"Factor this out as `addressOrPrefix(s string) (net.IP, net.IPMask, error)`, and reuse it in addAddrFromSpec.","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"d2203e4d92506b305790a40cc1ceeb7fcc649d92","unresolved":false,"context_lines":[{"line_number":323,"context_line":""},{"line_number":324,"context_line":"func routeFromSpec(r *netpb.Interface_Route, link netlink.Link) error {"},{"line_number":325,"context_line":"\tvar route netlink.Route"},{"line_number":326,"context_line":"\tif strings.ContainsRune(r.Destination, \u0027/\u0027) {"},{"line_number":327,"context_line":"\t\t_, dstPrefix, err :\u003d net.ParseCIDR(r.Destination)"},{"line_number":328,"context_line":"\t\tif err !\u003d nil {"},{"line_number":329,"context_line":"\t\t\treturn fmt.Errorf(\"failed parsing %q as CIDR: %w\", r.Destination, err)"},{"line_number":330,"context_line":"\t\t}"},{"line_number":331,"context_line":"\t\troute.Dst \u003d dstPrefix"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"\t} else {"},{"line_number":334,"context_line":"\t\tdstIP :\u003d net.ParseIP(r.Destination)"},{"line_number":335,"context_line":"\t\tif dstIP \u003d\u003d nil {"},{"line_number":336,"context_line":"\t\t\treturn fmt.Errorf(\"failed parsing %q as IP\", r.Destination)"},{"line_number":337,"context_line":"\t\t}"},{"line_number":338,"context_line":"\t\troute.Dst.IP \u003d dstIP"},{"line_number":339,"context_line":"\t\troute.Dst.Mask \u003d singleHostMask(dstIP)"},{"line_number":340,"context_line":"\t}"},{"line_number":341,"context_line":"\troute.Protocol \u003d unix.RTPROT_STATIC"},{"line_number":342,"context_line":"\troute.LinkIndex \u003d link.Attrs().Index"},{"line_number":343,"context_line":"\troute.Priority \u003d int(r.Metric)"}],"source_content_type":"text/x-go","patch_set":6,"id":"7de1b315_da58955d","line":340,"range":{"start_line":326,"start_character":1,"end_line":340,"end_character":2},"in_reply_to":"f89b5a92_29b38250","updated":"2023-03-30 16:05:42.000000000","message":"Done","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"9e126a446f508724e5f03b51a3cedff292d367df","unresolved":true,"context_lines":[{"line_number":338,"context_line":"\t\troute.Dst.IP \u003d dstIP"},{"line_number":339,"context_line":"\t\troute.Dst.Mask \u003d singleHostMask(dstIP)"},{"line_number":340,"context_line":"\t}"},{"line_number":341,"context_line":"\troute.Protocol \u003d unix.RTPROT_STATIC"},{"line_number":342,"context_line":"\troute.LinkIndex \u003d link.Attrs().Index"},{"line_number":343,"context_line":"\troute.Priority \u003d int(r.Metric)"},{"line_number":344,"context_line":"\tif r.SourceIp !\u003d \"\" {"}],"source_content_type":"text/x-go","patch_set":6,"id":"3ebc47f0_b01637db","line":341,"range":{"start_line":341,"start_character":7,"end_line":341,"end_character":15},"updated":"2023-03-30 15:15:45.000000000","message":"Don\u0027t we want a custom protocol here, too?","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000002,"name":"Serge Bazanski","display_name":"Serge","email":"serge@monogon.tech","username":"serge","avatars":[{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/52c41428b6369f2c02b9717425216f7d.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"85db2c880c51e0f55b3ae3baa8f94eede5bf38b3","unresolved":false,"context_lines":[{"line_number":338,"context_line":"\t\troute.Dst.IP \u003d dstIP"},{"line_number":339,"context_line":"\t\troute.Dst.Mask \u003d singleHostMask(dstIP)"},{"line_number":340,"context_line":"\t}"},{"line_number":341,"context_line":"\troute.Protocol \u003d unix.RTPROT_STATIC"},{"line_number":342,"context_line":"\troute.LinkIndex \u003d link.Attrs().Index"},{"line_number":343,"context_line":"\troute.Priority \u003d int(r.Metric)"},{"line_number":344,"context_line":"\tif r.SourceIp !\u003d \"\" {"}],"source_content_type":"text/x-go","patch_set":6,"id":"7f39412b_02b31e26","line":341,"range":{"start_line":341,"start_character":7,"end_line":341,"end_character":15},"in_reply_to":"0990a813_250e043f","updated":"2023-03-30 16:28:39.000000000","message":"Ack","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"d2203e4d92506b305790a40cc1ceeb7fcc649d92","unresolved":true,"context_lines":[{"line_number":338,"context_line":"\t\troute.Dst.IP \u003d dstIP"},{"line_number":339,"context_line":"\t\troute.Dst.Mask \u003d singleHostMask(dstIP)"},{"line_number":340,"context_line":"\t}"},{"line_number":341,"context_line":"\troute.Protocol \u003d unix.RTPROT_STATIC"},{"line_number":342,"context_line":"\troute.LinkIndex \u003d link.Attrs().Index"},{"line_number":343,"context_line":"\troute.Priority \u003d int(r.Metric)"},{"line_number":344,"context_line":"\tif r.SourceIp !\u003d \"\" {"}],"source_content_type":"text/x-go","patch_set":6,"id":"0990a813_250e043f","line":341,"range":{"start_line":341,"start_character":7,"end_line":341,"end_character":15},"in_reply_to":"3ebc47f0_b01637db","updated":"2023-03-30 16:05:42.000000000","message":"Considering that this is the closest thing we have to administratively configured static routes I went with RTPROT_STATIC. There should be nothing else using RTPROT_STATIC as this service is the only thing accepting static routes. These are only used for routes explicitly in the specification, any dynamic routes from for example DHCP have their own protocol.","commit_id":"d7cdaf21777a05ab7ada1ab6bfae1c961bf2b291"}]}
