1. 07 May, 2019 2 commits
    • Thomas Haller's avatar
      libnm: use macro and designated initializers for NMVariantAttributeSpec · 86dc50d4
      Thomas Haller authored
      I think initializing structs should (almost) be always done with designated
      initializers, because otherwise it's easy to get the order wrong. The
      problem is that otherwise the order of fields gets additional meaning
      not only for the memory layout, but also for the code that initialize
      the structs.
      
      Add a macro NM_VARIANT_ATTRIBUTE_SPEC_DEFINE() that replaces the other
      (duplicate) macros. This macro also gets it right to mark the struct as
      const.
      86dc50d4
    • Thomas Haller's avatar
      libnm: mark NMVariantAttributeSpec pointers as const · 4e3955e6
      Thomas Haller authored
      This actually allows the compiler/linker to mark the memory as read-only and any
      modification will cause a segmentation fault.
      
      I would also think that it allows the compiler to put the structure directly
      beside the outer constant array (in which this pointer is embedded). That is good
      locality-wise.
      4e3955e6
  2. 01 May, 2019 1 commit
    • Thomas Haller's avatar
      libnm: pass connection to compare_property() function · b1344b6b
      Thomas Haller authored
      We have certain artificial properties that not only depend on one
      property alone or that depend on a property in another(!) setting.
      
      For that, we have synth_func.
      
      Other than that, synth_func and get_func are really fundamentally
      similar and should be merged. That is because the distinction whether a
      property value is "synthetized" or just based on a plain property is
      minor. It's better to have the general concept of "convert property to
      GVariant" in one form only.
      
      Note that compare_property() is by default implemented based
      on get_func. Hence, if get_func and synth_func get merged,
      compare_property() will also require access to the NMConnection.
      
      Also it makes some sense: some properties are artificial and actually
      stored in "another" setting of the connection. But still, the property
      descriptor for the property is in this setting. The example is the
      "bond.interface-name" which only exists on D-Bus. It's stored as
      "connection.interface-name".
      I don't really like to say "exists on D-Bus only". It's still a valid
      property, despite in NMSetting it's stored somehow differently (or not
      at all). So, this is also just a regular property for which we have a
      property-info vtable.
      Does it make sense to compare such properties? Maybe. But the point is that
      compare_property() function needs sometimes access to the entire
      connection. So add the argument.
      b1344b6b
  3. 20 Apr, 2019 2 commits
  4. 17 Apr, 2019 2 commits
    • Thomas Haller's avatar
      libnm: use nm_utils_escaped_tokens_*() for parsing NMIPRoutingRule · 2d1ae8dd
      Thomas Haller authored
      Replace nm_utils_str_simpletokens_extract_next() by
      nm_utils_escaped_tokens_split().
      
      nm_utils_escaped_tokens_split() should become our first choice for
      parsing and tokenizing.
      
      Note that both nm_utils_str_simpletokens_extract_next() and
      nm_utils_escaped_tokens_split() need to strdup the string once,
      and tokenizing takes O(n). So, they are roughtly the same performance
      wise. The only difference is, that as we iterate through the tokens,
      we might abort early on error with nm_utils_str_simpletokens_extract_next()
      and not parse the entire string. But that is a small benefit, since we
      anyway always strdup() the string (being O(n) already).
      
      Note that to-string will no longer escape ',' and ';'. This is a change
      in behavior, of unreleased API. Also note, that escaping these is no
      longer necessary, because nmcli soon will also use nm_utils_escaped_tokens_*().
      
      Another change in behavior is that nm_utils_str_simpletokens_extract_next()
      treated invalid escape sequences (backslashes followed by an arbitrary
      character), buy stripping the backslash. nm_utils_escaped_tokens_*()
      leaves such backslashes as is, and only honors them if they are followed
      by a whitespace (the delimiter) or another backslash. The disadvantage
      of the new approach is that backslashes are treated differently
      depending on the following character. The benefit is, that most
      backslashes can now be written verbatim, not requiring them to escape
      them with a double-backslash.
      
      Yes, there is a problem with these nested escape schemes:
      
        - the caller may already need to escape backslash in shell.
      
        - then nmcli will use backslash escaping to split the rules at ','.
      
        - then nm_ip_routing_rule_from_string() will honor backslash escaping
          for spaces.
      
        - then iifname and oifname use backslash escaping for nm_utils_buf_utf8safe_escape()
          to express non-UTF-8 characters (because interface names are not
          necessarily UTF-8).
      
      This is only redeamed because escaping is really only necessary for very
      unusual cases, if you want to embed a backslash, a space, a comma, or a
      non-UTF-8 character. But if you have to, now you will be able to express
      that.
      
      The other upside of these layers of escaping is that they become all
      indendent from each other:
      
        - shell can accept quoted/escaped arguments and will unescape them.
      
        - nmcli can do the tokenizing for ',' (and escape the content
          unconditionally when converting to string).
      
        - nm_ip_routing_rule_from_string() can do its tokenizing without
          special consideration of utf8safe escaping.
      
        - NMIPRoutingRule takes iifname/oifname as-is and is not concerned
          about nm_utils_buf_utf8safe_escape(). However, before configuring
          the rule in kernel, this utf8safe escape will be unescaped to get
          the interface name (which is non-UTF8 binary).
      
      (cherry picked from commit b6d0be2d)
      2d1ae8dd
    • Thomas Haller's avatar
      libnm: use nm_utils_escaped_tokens_*() for parsing NMIPRoutingRule · b6d0be2d
      Thomas Haller authored
      Replace nm_utils_str_simpletokens_extract_next() by
      nm_utils_escaped_tokens_split().
      
      nm_utils_escaped_tokens_split() should become our first choice for
      parsing and tokenizing.
      
      Note that both nm_utils_str_simpletokens_extract_next() and
      nm_utils_escaped_tokens_split() need to strdup the string once,
      and tokenizing takes O(n). So, they are roughtly the same performance
      wise. The only difference is, that as we iterate through the tokens,
      we might abort early on error with nm_utils_str_simpletokens_extract_next()
      and not parse the entire string. But that is a small benefit, since we
      anyway always strdup() the string (being O(n) already).
      
      Note that to-string will no longer escape ',' and ';'. This is a change
      in behavior, of unreleased API. Also note, that escaping these is no
      longer necessary, because nmcli soon will also use nm_utils_escaped_tokens_*().
      
      Another change in behavior is that nm_utils_str_simpletokens_extract_next()
      treated invalid escape sequences (backslashes followed by an arbitrary
      character), buy stripping the backslash. nm_utils_escaped_tokens_*()
      leaves such backslashes as is, and only honors them if they are followed
      by a whitespace (the delimiter) or another backslash. The disadvantage
      of the new approach is that backslashes are treated differently
      depending on the following character. The benefit is, that most
      backslashes can now be written verbatim, not requiring them to escape
      them with a double-backslash.
      
      Yes, there is a problem with these nested escape schemes:
      
        - the caller may already need to escape backslash in shell.
      
        - then nmcli will use backslash escaping to split the rules at ','.
      
        - then nm_ip_routing_rule_from_string() will honor backslash escaping
          for spaces.
      
        - then iifname and oifname use backslash escaping for nm_utils_buf_utf8safe_escape()
          to express non-UTF-8 characters (because interface names are not
          necessarily UTF-8).
      
      This is only redeamed because escaping is really only necessary for very
      unusual cases, if you want to embed a backslash, a space, a comma, or a
      non-UTF-8 character. But if you have to, now you will be able to express
      that.
      
      The other upside of these layers of escaping is that they become all
      indendent from each other:
      
        - shell can accept quoted/escaped arguments and will unescape them.
      
        - nmcli can do the tokenizing for ',' (and escape the content
          unconditionally when converting to string).
      
        - nm_ip_routing_rule_from_string() can do its tokenizing without
          special consideration of utf8safe escaping.
      
        - NMIPRoutingRule takes iifname/oifname as-is and is not concerned
          about nm_utils_buf_utf8safe_escape(). However, before configuring
          the rule in kernel, this utf8safe escape will be unescaped to get
          the interface name (which is non-UTF8 binary).
      b6d0be2d
  5. 12 Apr, 2019 1 commit
  6. 10 Apr, 2019 1 commit
  7. 27 Mar, 2019 2 commits
    • Thomas Haller's avatar
      6e6d1e07
    • Thomas Haller's avatar
      libnm: add NMIPRoutingRule API · 7fb23b0a
      Thomas Haller authored
      Add NMIPRoutingRule API with a few basic rule properties. More
      properties will be added later as we want to support them.
      
      Also, add to/from functions for string/GVariant representations.
      These will be needed to persist/load/exchange rules.
      
      The to-string format follows the `ip rule add` syntax, with the aim
      to be partially compatible. Full compatibility is not possible though,
      for various reasons (see code comment).
      7fb23b0a
  8. 07 Mar, 2019 2 commits
  9. 12 Feb, 2019 1 commit
  10. 21 Jan, 2019 1 commit
  11. 15 Jan, 2019 2 commits
    • Thomas Haller's avatar
      libnm-core: reorder code in settings · 19141ef7
      Thomas Haller authored
      Order the code in our common way. No other changes.
      
      - ensure to include the main header first (directly after
        "nm-default.h").
      
      - reorder function definitions: get_property(), set_property(),
        *_init(), *_new(), finalize(), *_class_init().
      19141ef7
    • Thomas Haller's avatar
      libnm-core: cleanup NMSetting's class initialization · a3d6976e
      Thomas Haller authored
      Unify the coding style for class-init functions in libnm-core.
      
      Also make use of obj_properties, NM_GOBJECT_PROPERTIES_DEFINE(), and
      _notify().
      a3d6976e
  12. 11 Jan, 2019 1 commit
    • Thomas Haller's avatar
      libnm: rework compare_property() implementation for NMSetting · 885c872d
      Thomas Haller authored
      NMSetting's compare_property() has and had two callers:
      nm_setting_compare() and nm_setting_diff().
      
      compare_property() accepts a NMSettingCompareFlags argument, but
      at the same time, both callers have another complex (and
      inconsistent!) set of pre-checks for shortcuting the call of
      compare_property(): should_compare_prop().
      
      Merge should_compare_prop() into compare_property(). This way,
      nm_setting_compare() and nm_setting_diff() has less additional
      code, and are simpler to follow. Especially nm_setting_compare()
      is now trivial. And nm_setting_diff() is still complicated, but
      not related to the question how the property compares or whether
      it should be compared at all.
      
      If you want to know whether it should be compared, all you need to do
      now is follow NMSettingClass.compare_property().
      
      This changes function pointer NMSettingClass.compare_property(),
      which is public API. However, no user can actually use this (and shall
      not!), because _nm_setting_class_commit_full() etc. is private API. A
      user outside of libnm-core cannot create his/her own subclasses of
      NMSetting, and never could in the past. So, this API/ABI change doesn't
      matter.
      885c872d
  13. 13 Nov, 2018 1 commit
  14. 06 Oct, 2018 1 commit
  15. 07 Sep, 2018 1 commit
  16. 11 Aug, 2018 1 commit
  17. 10 Aug, 2018 2 commits
    • Thomas Haller's avatar
      libnm: rework setting metadata for property handling · 37938043
      Thomas Haller authored
      NMSetting internally already tracked a list of all proper GObject properties
      and D-Bus-only properties.
      
      Rework the tracking of the list, so that:
      
      - instead of attaching the data to the GType of the setting via
        g_type_set_qdata(), it is tracked in a static array indexed by
        NMMetaSettingType. This allows to find the setting-data by simple
        pointer arithmetic, instead of taking a look and iterating (like
        g_type_set_qdata() does).
      
        Note, that this is still thread safe, because the static table entry is
        initialized in the class-init function with _nm_setting_class_commit().
        And it only accessed by following a NMSettingClass instance, thus
        the class constructor already ran (maybe not for all setting classes,
        but for the particular one that we look up).
      
        I think this makes initialization of the metadata simpler to
        understand.
        Previously, in a first phase each class would attach the metadata
        to the GType as setting_property_overrides_quark(). Then during
        nm_setting_class_ensure_properties() it would merge them and
        set as setting_properties_quark(). Now, during the first phase,
        we only incrementally build a properties_override GArray, which
        we finally hand over during nm_setting_class_commit().
      
      - sort the property infos by name and do binary search.
      
      Also expose this meta data types as internal API in nm-setting-private.h.
      While not accessed yet, it can prove beneficial, to have direct (internal)
      access to these structures.
      
      Also, rename NMSettingProperty to NMSettInfoProperty to use a distinct
      naming scheme. We already have 40+ subclasses of NMSetting that are called
      NMSetting*. Likewise, NMMetaSetting* is heavily used already. So, choose a
      new, distinct name.
      37938043
    • Thomas Haller's avatar
      libnm/trivial: cleanup variable names in settings' class-init functions · 23adc373
      Thomas Haller authored
      - Don't use @parent_class name. This local variable (and @object_class) is
        the class instance up-cast to the pointer types of the parents. The point
        here is not that it is the direct parent. The point is, that it's the
        NMSettingClass type.
        Also, it can only be used inconsistently, in face of NMSettingIP4Config,
        who's parent type is NMSettingIPConfig. Clearly, inside
        nm-setting-ip4-config.c we wouldn't want to use the "parent_class"
        name. Consistently rename @parent_class to @setting_class.
      
      - Also rename the pointer to the own class to @klass. "setting_class" is also the
        wrong name for that, because the right name would be something like
        "setting_6lowpan_class".
        However, "klass" is preferred over the latter, because we commonly create new
        GObject implementations by copying an existing one. Generic names like "klass"
        and "self" inside a type implementation make that simpler.
      
      - drop useless comments like
      
           /* virtual functions */
           /* Properties */
      
        It's better to logically and visually structure the code, and avoid trival
        remarks about that. They only end up being used inconsistently. If you
        even need a stronger visual separator, then an 80 char /****/ line
        should be preferred.
      23adc373
  18. 11 Jul, 2018 2 commits
    • Beniamino Galvani's avatar
      libnm-core: don't emit signal when clearing lists already empty · a2846bd7
      Beniamino Galvani authored
      If the property is a list and it is already empty, we should not emit
      a signal when it gets cleared.
      a2846bd7
    • Thomas Haller's avatar
      all: don't use gchar/gshort/gint/glong but C types · e1c7a2b5
      Thomas Haller authored
      We commonly don't use the glib typedefs for char/short/int/long,
      but their C types directly.
      
          $ git grep '\<g\(char\|short\|int\|long\|float\|double\)\>' | wc -l
          587
          $ git grep '\<\(char\|short\|int\|long\|float\|double\)\>' | wc -l
          21114
      
      One could argue that using the glib typedefs is preferable in
      public API (of our glib based libnm library) or where it clearly
      is related to glib, like during
      
        g_object_set (obj, PROPERTY, (gint) value, NULL);
      
      However, that argument does not seem strong, because in practice we don't
      follow that argument today, and seldomly use the glib typedefs.
      Also, the style guide for this would be hard to formalize, because
      "using them where clearly related to a glib" is a very loose suggestion.
      
      Also note that glib typedefs will always just be typedefs of the
      underlying C types. There is no danger of glib changing the meaning
      of these typedefs (because that would be a major API break of glib).
      
      A simple style guide is instead: don't use these typedefs.
      
      No manual actions, I only ran the bash script:
      
        FILES=($(git ls-files '*.[hc]'))
        sed -i \
            -e 's/\<g\(char\|short\|int\|long\|float\|double\)\>\( [^ ]\)/\1\2/g' \
            -e 's/\<g\(char\|short\|int\|long\|float\|double\)\>  /\1   /g' \
            -e 's/\<g\(char\|short\|int\|long\|float\|double\)\>/\1/g' \
            "${FILES[@]}"
      e1c7a2b5
  19. 14 May, 2018 1 commit
  20. 18 Apr, 2018 1 commit
  21. 27 Mar, 2018 1 commit
  22. 26 Mar, 2018 1 commit
  23. 12 Jan, 2018 1 commit
    • Beniamino Galvani's avatar
      dns: introduce routing domains · e91f1a7d
      Beniamino Galvani authored
      Similarly to what systemd-resolved does, introduce the concept of
      "routing" domain, which is a domain in the search list that is used
      only to decide the interface over which a query must be forwarded, but
      is not used to complete unqualified host names. Routing domains are
      those starting with a tilde ('~') before the actual domain name.
      
      Domains without the initial tilde are used both for completing
      unqualified names and for the routing decision.
      e91f1a7d
  24. 18 Dec, 2017 4 commits
  25. 11 Dec, 2017 1 commit
    • Lubomir Rintel's avatar
      libnm-core/utils: add some special properties for the attributes · 47b1dc38
      Lubomir Rintel authored
      "no_value" indicates that the the attribute is a single word, not a
      key=value pair. If the type is BOOLEAN then the attribute is considered
      true, if it's a STRING then the key is used instead of a value.
      
      "consumes_rest" indicates that the particular key takes the unparseable
      tail of the string for a value.
      
      This allows parsing tc-style strings. Consider this filter:
      
                    ,------ regular key/value pair
             ,-----'----.
        root handle 1234: matchall action simple foo bar baz
          |                  |     `-----------.-----------'
          |                  |                 `- "", STRING, consumes_rest
          |                  `------------------- "kind", STRING, no_value
          `-------------------------------------- "root', BOOLEAN, no_value
      47b1dc38
  26. 30 Nov, 2017 1 commit
  27. 16 Nov, 2017 1 commit
    • Thomas Haller's avatar
      all: use nm_str_hash() instead of g_str_hash() · a6be2f4a
      Thomas Haller authored
      We also do this for libnm and libnm-core, where it causes visible changes
      in behavior. But if somebody would rely on the hashing implementation
      for hash tables, it would be seriously flawed.
      a6be2f4a
  28. 13 Nov, 2017 1 commit
    • Thomas Haller's avatar
      all: support route-attribute "onlink" for IPv4 · 0ed49717
      Thomas Haller authored
      Kernel doesn't support it for IPv6.
      
      This is especially useful, if you combine static routes
      with DHCP. In that case, you might want to get the device-route
      to the gateway automatically, but add a static-route for it.
      0ed49717
  29. 30 Oct, 2017 1 commit