func: _eth_get_rss_ex_src_addr(const struct iovec *pkt, int pkt_frags,
  
                          size_t dsthdr_offset,
  
                          struct ip6_ext_hdr *ext_hdr,
  
                          struct in6_address *src_addr)
  
  {
  
      size_t bytes_left = (ext_hdr->ip6r_len + 1) * 8 - sizeof(*ext_hdr);
  
      struct ip6_option_hdr opthdr;
  
      size_t opt_offset = dsthdr_offset + sizeof(*ext_hdr);
  
  
  
      while (bytes_left > sizeof(opthdr)) {
  
          size_t input_size = iov_size(pkt, pkt_frags);
  
          size_t bytes_read, optlen;
  
  
  
          if (input_size < opt_offset) {
  
              return false;
  
          }
  
  
  
          bytes_read = iov_to_buf(pkt, pkt_frags, opt_offset,
  
                                  &opthdr, sizeof(opthdr));
  
  
  
          if (bytes_read != sizeof(opthdr)) {
  
              return false;
  
          }
  
  
  
          optlen = (opthdr.type == IP6_OPT_PAD1) ? 1
  
                                                 : (opthdr.len + sizeof(opthdr));
  
  
  
          if (optlen > bytes_left) {
  
              return false;
  
          }
  
  
  
          if (opthdr.type == IP6_OPT_HOME) {
  
              size_t input_size = iov_size(pkt, pkt_frags);
  
  
  
              if (input_size < opt_offset + sizeof(opthdr)) {
  
                  return false;
  
              }
  
  
  
              bytes_read = iov_to_buf(pkt, pkt_frags,
  
                                      opt_offset + sizeof(opthdr),
  
                                      src_addr, sizeof(*src_addr));
  
  
  
              return bytes_read == sizeof(src_addr);
  
          }
  
  
  
          opt_offset += optlen;
  
          bytes_left -= optlen;
  
      }
  
  
  
      return false;
  
  }
  