diff -ruN a/src/dnsmasq.h b/src/dnsmasq.h
--- a/src/dnsmasq.h	2021-04-07 20:39:39.000000000 +0000
+++ b/src/dnsmasq.h	2026-02-05 05:29:47.085876046 +0000
@@ -570,6 +570,7 @@
   unsigned int queries, failed_queries;
 #ifdef HAVE_LOOP
   u32 uid;
+  int trust;
 #endif
   struct server *next; 
 };
@@ -1019,6 +1020,16 @@
   struct dhcp_relay *current, *next;
 };
 
+struct net_mask_t {
+  struct in_addr net;
+  in_addr_t mask;
+};
+
+struct net_list_t {
+  int entries;
+  struct net_mask_t *nets;
+};
+
 extern struct daemon {
   /* datastuctures representing the command-line and 
      config file arguments. All set (including defaults)
@@ -1052,6 +1063,7 @@
   char *lease_change_command;
   struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces;
   struct bogus_addr *bogus_addr, *ignore_addr;
+  struct net_list_t *chnroutes_list;
   struct server *servers;
   struct ipsets *ipsets;
   int log_fac; /* log facility */
@@ -1250,7 +1262,7 @@
 		      time_t now, int ad_reqd, int do_bit, int have_pseudoheader);
 int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, 
 			     time_t now);
-int check_for_ignored_address(struct dns_header *header, size_t qlen);
+int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr, const struct net_list_t *netlist);
 int check_for_local_domain(char *name, time_t now);
 size_t resize_packet(struct dns_header *header, size_t plen, 
 		  unsigned char *pheader, size_t hlen);
@@ -1351,8 +1363,9 @@
 void reset_option_bool(unsigned int opt);
 struct hostsfile *expand_filelist(struct hostsfile *list);
 char *parse_server(char *arg, union mysockaddr *addr, 
-		   union mysockaddr *source_addr, char *interface, int *flags);
+		   union mysockaddr *source_addr, char *interface, int *flags, int *trust);
 int option_read_dynfile(char *file, int flags);
+int cmp_net_mask(const void *a, const void *b);
 
 /* forward.c */
 void reply_query(int fd, time_t now);
diff -ruN a/src/forward.c b/src/forward.c
--- a/src/forward.c	2021-04-07 20:39:39.000000000 +0000
+++ b/src/forward.c	2026-02-05 05:31:37.708142365 +0000
@@ -886,9 +886,16 @@
   daemon->log_source_addr = &forward->frec_src.source;
   
   if (daemon->ignore_addr && RCODE(header) == NOERROR &&
-      check_for_ignored_address(header, n))
+      check_for_ignored_address(header, n, daemon->ignore_addr, NULL))
     return;
 
+  if ((server->trust == 0 || server->trust == 1) && daemon->chnroutes_list && RCODE(header) == NOERROR)
+    {
+      int c = check_for_ignored_address(header, n, NULL, daemon->chnroutes_list);
+      if (server->trust == 0 && c == 0) return; /* untrust dns server, and got not in chnroutes address */
+      if (server->trust == 1 && c == 1) return; /* trust dns server, and got in chnroutes address */
+    }
+
   /* Note: if we send extra options in the EDNS0 header, we can't recreate
      the query from the reply. */
   if ((RCODE(header) == REFUSED || RCODE(header) == SERVFAIL) &&
diff -ruN a/src/option.c b/src/option.c
--- a/src/option.c	2021-04-07 20:39:39.000000000 +0000
+++ b/src/option.c	2026-02-05 05:33:53.140072615 +0000
@@ -157,6 +157,7 @@
 #define LOPT_DHCPTTL       348
 #define LOPT_TFTP_MTU      349
 #define LOPT_REPLY_DELAY   350
+#define LOPT_CHNROUTES_FILE 999
 #define LOPT_RAPID_COMMIT  351
 #define LOPT_DUMPFILE      352
 #define LOPT_DUMPMASK      353
@@ -205,6 +206,7 @@
     { "bogus-priv", 0, 0, 'b' },
     { "bogus-nxdomain", 1, 0, 'B' },
     { "ignore-address", 1, 0, LOPT_IGNORE_ADDR },
+    { "chnroutes-file", 1, 0, LOPT_CHNROUTES_FILE },
     { "selfmx", 0, 0, 'e' },
     { "filterwin2k", 0, 0, 'f' },
     { "pid-file", 2, 0, 'x' },
@@ -521,6 +523,7 @@
   { LOPT_LOCAL_SERVICE, OPT_LOCAL_SERVICE, NULL, gettext_noop("Accept queries only from directly-connected networks."), NULL },
   { LOPT_LOOP_DETECT, OPT_LOOP_DETECT, NULL, gettext_noop("Detect and remove DNS forwarding loops."), NULL },
   { LOPT_IGNORE_ADDR, ARG_DUP, "<ipaddr>", gettext_noop("Ignore DNS responses containing ipaddr."), NULL }, 
+  { LOPT_CHNROUTES_FILE, ARG_ONE, "<path>", gettext_noop("Trust dns server not containing ipaddr, untrust dns server containing ipaddr."), NULL }, 
   { LOPT_DHCPTTL, ARG_ONE, "<ttl>", gettext_noop("Set TTL in DNS responses with DHCP-derived addresses."), NULL }, 
   { LOPT_REPLY_DELAY, ARG_ONE, "<integer>", gettext_noop("Delay DHCP replies for at least number of seconds."), NULL },
   { LOPT_RAPID_COMMIT, OPT_RAPID_COMMIT, NULL, gettext_noop("Enables DHCPv4 Rapid Commit option."), NULL },
@@ -787,14 +790,15 @@
   return NULL;
 }
 
-char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags)
+char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags, int *trust)
 {
   int source_port = 0, serv_port = NAMESERVER_PORT;
-  char *portno, *source;
+  char *portno, *source, *trust_type;
   char *interface_opt = NULL;
   int scope_index = 0;
   char *scope_id;
   
+  *trust = -1;
   if (!arg || strlen(arg) == 0)
     {
       *flags |= SERV_NO_ADDR;
@@ -802,6 +806,10 @@
       return NULL;
     }
 
+  if ((trust_type = split_chr(arg, ',')) && /* is there a server#port,trust. */
+      !atoi_check16(trust_type, trust))
+    return _("bad trust type");
+
   if ((source = split_chr(arg, '@')) && /* is there a source. */
       (portno = split_chr(source, '#')) &&
       !atoi_check16(portno, &source_port))
@@ -903,6 +911,9 @@
   char *p;
 
   memset(serv, 0, sizeof(struct server));
+#ifdef HAVE_LOOP
+  serv->trust = -1;
+#endif
   p = serv->domain = opt_malloc(29); /* strlen("xxx.yyy.zzz.ttt.in-addr.arpa")+1 */
 
   switch (msize)
@@ -942,6 +953,9 @@
   int i;
 				  
   memset(serv, 0, sizeof(struct server));
+#ifdef HAVE_LOOP
+  serv->trust = -1;
+#endif
   p = serv->domain = opt_malloc(73); /* strlen("32*<n.>ip6.arpa")+1 */
   
   for (i = msize-1; i >= 0; i -= 4)
@@ -1650,6 +1664,64 @@
     }
 }
 
+int cmp_net_mask(const void *a, const void *b)
+{
+  struct net_mask_t *neta = (struct net_mask_t *)a;
+  struct net_mask_t *netb = (struct net_mask_t *)b;
+  if (neta->net.s_addr == netb->net.s_addr)
+    return 0;
+  if (ntohl(neta->net.s_addr) > ntohl(netb->net.s_addr))
+    return 1;
+  return -1;
+}
+
+static int parse_chnroutes(const char *filename, struct net_list_t *chnroutes_list)
+{
+  FILE *fp;
+  char line_buf[32];
+  char *line;
+  size_t len = sizeof(line_buf);
+  chnroutes_list->entries = 0;
+  int i = 0;
+
+  fp = fopen(filename, "rb");
+  if (fp == NULL)
+    return -1;
+
+  while ((line = fgets(line_buf, len, fp)))
+    chnroutes_list->entries++;
+
+  chnroutes_list->nets = calloc(chnroutes_list->entries, sizeof(struct net_mask_t));
+  if (0 != fseek(fp, 0, SEEK_SET))
+    return -1;
+
+  while ((line = fgets(line_buf, len, fp)))
+    {
+      char *sp_pos;
+      sp_pos = strchr(line, '\r');
+      if (sp_pos) *sp_pos = 0;
+      sp_pos = strchr(line, '\n');
+      if (sp_pos) *sp_pos = 0;
+      sp_pos = strchr(line, '/');
+      if (sp_pos)
+        {
+          *sp_pos = 0;
+          chnroutes_list->nets[i].mask = (1 << (32 - atoi(sp_pos + 1))) - 1;
+        }
+      else
+        chnroutes_list->nets[i].mask = UINT32_MAX;
+
+      if (0 == inet_aton(line, &chnroutes_list->nets[i].net))
+        return (i+1);
+      i++;
+    }
+
+  qsort(chnroutes_list->nets, chnroutes_list->entries, sizeof(struct net_mask_t), cmp_net_mask);
+
+  fclose(fp);
+  return 0;
+}
+
 static int one_opt(int option, char *arg, char *errstr, char *gen_err, int command_line, int servers_only)
 {      
   int i;
@@ -2290,6 +2362,9 @@
 				  /* local=/<domain>/ */
 				  serv = opt_malloc(sizeof(struct server));
 				  memset(serv, 0, sizeof(struct server));
+#ifdef HAVE_LOOP
+  serv->trust = -1;
+#endif
 				  serv->domain = d;
 				  serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
 				  serv->next = daemon->servers;
@@ -2333,6 +2408,9 @@
 				  /* local=/<domain>/ */
 				  serv = opt_malloc(sizeof(struct server));
 				  memset(serv, 0, sizeof(struct server));
+#ifdef HAVE_LOOP
+  serv->trust = -1;
+#endif
 				  serv->domain = d;
 				  serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
 				  serv->next = daemon->servers;
@@ -2484,6 +2562,21 @@
       } while (arg);
       break;
       
+    case LOPT_CHNROUTES_FILE: /* --chnroutes-file */
+      {
+        struct net_list_t *crlist = opt_malloc(sizeof(struct net_list_t));
+        int r = parse_chnroutes(opt_string_alloc(arg), crlist);
+        if (r < 0)
+          ret_err(_("chnroutes file open fail."));
+        if (r > 0)
+          {
+            my_syslog(LOG_ERR, _("chnroutes file has wrong entry, line: %d"), r);
+            ret_err(_("chnroutes file has wrong entry."));
+          }
+        daemon->chnroutes_list = crlist;
+        break;
+      }
+
     case 'B':  /* --bogus-nxdomain */
     case LOPT_IGNORE_ADDR: /* --ignore-address */
      {
@@ -2583,6 +2676,9 @@
 		  ret_err(gen_err);
 		serv = opt_malloc(sizeof(struct server));
 		memset(serv, 0, sizeof(struct server));
+#ifdef HAVE_LOOP
+		serv->trust = -1;
+#endif
 		serv->next = newlist;
 		newlist = serv;
 		serv->domain = domain;
@@ -2599,6 +2695,9 @@
 	    newlist = opt_malloc(sizeof(struct server));
 	    memset(newlist, 0, sizeof(struct server));
 #ifdef HAVE_LOOP
+	    newlist->trust = -1;
+#endif
+#ifdef HAVE_LOOP
 	    newlist->uid = rand32();
 #endif
 	  }
@@ -2628,7 +2727,7 @@
 	  newlist->flags |= SERV_USE_RESOLV; /* treat in ordinary way */
 	else
 	  {
-	    char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags);
+	    char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags, &newlist->trust);
 	    if (err)
 	      {
 	        server_list_free(newlist);
@@ -2678,7 +2777,7 @@
 	else
 	  ret_err(gen_err);
  
-	string = parse_server(comma, &serv->addr, &serv->source_addr, serv->interface, &serv->flags);
+	string = parse_server(comma, &serv->addr, &serv->source_addr, serv->interface, &serv->flags, &serv->trust);
 	
 	if (string)
 	  ret_err(string);
diff -ruN a/src/rfc1035.c b/src/rfc1035.c
--- a/src/rfc1035.c	2021-04-07 20:39:39.000000000 +0000
+++ b/src/rfc1035.c	2026-02-05 05:34:24.077917449 +0000
@@ -1087,9 +1087,83 @@
   return 0;
 }
 
-int check_for_ignored_address(struct dns_header *header, size_t qlen)
+static int test_ip_in_list(struct in_addr ip, const struct net_list_t *netlist)
 {
-  return check_bad_address(header, qlen, daemon->ignore_addr, NULL, NULL);
+  int l = 0, r = netlist->entries - 1;
+  int m, cmp;
+  if (netlist->entries == 0)
+    return 0;
+  struct net_mask_t ip_net;
+  ip_net.net = ip;
+  while (l != r)
+    {
+      m = (l + r) / 2;
+      cmp = cmp_net_mask(&ip_net, &netlist->nets[m]);
+      if (cmp == -1)
+        {
+          if (r != m)
+            r = m;
+          else
+            break;
+        }
+      else
+        {
+          if (l != m)
+            l = m;
+          else
+            break;
+        }
+    }
+
+  if ((ntohl(netlist->nets[l].net.s_addr) ^ ntohl(ip.s_addr)) &
+      (UINT32_MAX ^ netlist->nets[l].mask))
+    return 0;
+
+  return 1;
+}
+
+int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr, const struct net_list_t *netlist)
+{
+  unsigned char *p;
+  int i, qtype, qclass, rdlen;
+  struct bogus_addr *baddrp;
+
+  if (!(p = skip_questions(header, qlen)))
+    return 0;
+
+  for (i = ntohs(header->ancount); i != 0; i--)
+    {
+      if (!(p = skip_name(p, header, qlen, 10)))
+        return 0;
+
+      GETSHORT(qtype, p);
+      GETSHORT(qclass, p);
+      p += 4; /* skip ttl */
+      GETSHORT(rdlen, p);
+
+      if (qclass == C_IN && qtype == T_A)
+        {
+          struct in_addr addr;
+          if (!CHECK_LEN(header, p, qlen, INADDRSZ))
+            return 0;
+
+          memcpy(&addr, p, INADDRSZ);
+
+          if (baddr != NULL)
+            for (baddrp = baddr; baddrp; baddrp = baddrp->next)
+              if ((addr.s_addr & baddrp->mask.s_addr) == baddrp->addr.s_addr)
+                return 1;
+
+          if (netlist != NULL)
+            if (test_ip_in_list(addr, netlist))
+              return 1;
+        }
+
+      if (!ADD_RDLEN(header, p, qlen, rdlen))
+        return 0;
+    }
+
+  return 0;
 }
 
 int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp, 
